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/protected/stream_encoder.h svneol=native#text/plain
src/lib/libflac/include/share/alloc.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/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++/metadata.cpp svneol=native#text/plain
src/lib/libflac/libflac++/stream_decoder.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++/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/bitmath.c svneol=native#text/plain
src/lib/libflac/libflac/bitreader.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 src/lib/libflac/libflac/bitwriter.c svneol=native#text/plain

View File

@ -410,6 +410,10 @@ ifdef USE_NETWORK
DEFS += -DUSE_NETWORK DEFS += -DUSE_NETWORK
endif endif
# need to ensure FLAC functions are statically linked
DEFS += -DFLAC__NO_DLL
#------------------------------------------------- #-------------------------------------------------
# compile flags # 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
FLAC_LIB = $(OBJ)/libflac.a $(OBJ)/libflac++.a
#------------------------------------------------- #-------------------------------------------------
# defines needed by multiple make files # defines needed by multiple make files

View File

@ -40,29 +40,6 @@
#include "emu.h" #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 // 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) void address_map_entry::set_read_port(const device_t &device, const char *tag)
{ {
m_read.m_type = AMH_PORT; 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) void address_map_entry::set_write_port(const device_t &device, const char *tag)
{ {
m_write.m_type = AMH_PORT; 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) void address_map_entry::set_readwrite_port(const device_t &device, const char *tag)
{ {
m_read.m_type = AMH_PORT; 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.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) void address_map_entry::set_read_bank(const device_t &device, const char *tag)
{ {
m_read.m_type = AMH_BANK; 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) void address_map_entry::set_write_bank(const device_t &device, const char *tag)
{ {
m_write.m_type = AMH_BANK; 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) void address_map_entry::set_readwrite_bank(const device_t &device, const char *tag)
{ {
m_read.m_type = AMH_BANK; 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.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())); assert(unitmask_is_appropriate(bits, mask, func.name()));
m_read.m_type = AMH_DEVICE_SUBMAP; 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_read.m_mask = mask;
m_write.m_type = AMH_DEVICE_SUBMAP; 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_write.m_mask = mask;
m_submap_delegate = func; m_submap_delegate = func;
m_submap_bits = bits; 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_bits = 8;
m_read.m_mask = unitmask; m_read.m_mask = unitmask;
m_read.m_name = string; m_read.m_name = string;
m_read.set_tag(device, tag); device.subtag(m_read.m_tag, tag);
m_rdevice8 = func; 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_bits = 8;
m_write.m_mask = unitmask; m_write.m_mask = unitmask;
m_write.m_name = string; m_write.m_name = string;
m_write.set_tag(device, tag); device.subtag(m_write.m_tag, tag);
m_wdevice8 = func; 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_bits = 8;
m_read.m_mask = unitmask; m_read.m_mask = unitmask;
m_read.m_name = func.name(); m_read.m_name = func.name();
m_read.set_tag(device, tag); device.subtag(m_read.m_tag, tag);
m_rproto8 = func; 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_bits = 8;
m_write.m_mask = unitmask; m_write.m_mask = unitmask;
m_write.m_name = func.name(); m_write.m_name = func.name();
m_write.set_tag(device, tag); device.subtag(m_write.m_tag, tag);
m_wproto8 = func; 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_bits = 16;
m_read.m_mask = unitmask; m_read.m_mask = unitmask;
m_read.m_name = string; m_read.m_name = string;
m_read.set_tag(device, tag); device.subtag(m_read.m_tag, tag);
m_rdevice16 = func; 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_bits = 16;
m_write.m_mask = unitmask; m_write.m_mask = unitmask;
m_write.m_name = string; m_write.m_name = string;
m_write.set_tag(device, tag); device.subtag(m_write.m_tag, tag);
m_wdevice16 = func; 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_bits = 16;
m_read.m_mask = unitmask; m_read.m_mask = unitmask;
m_read.m_name = func.name(); m_read.m_name = func.name();
m_read.set_tag(device, tag); device.subtag(m_read.m_tag, tag);
m_rproto16 = func; 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_bits = 16;
m_write.m_mask = unitmask; m_write.m_mask = unitmask;
m_write.m_name = func.name(); m_write.m_name = func.name();
m_write.set_tag(device, tag); device.subtag(m_write.m_tag, tag);
m_wproto16 = func; 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_bits = 32;
m_read.m_mask = unitmask; m_read.m_mask = unitmask;
m_read.m_name = string; m_read.m_name = string;
m_read.set_tag(device, tag); device.subtag(m_read.m_tag, tag);
m_rdevice32 = func; 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_bits = 32;
m_write.m_mask = unitmask; m_write.m_mask = unitmask;
m_write.m_name = string; m_write.m_name = string;
m_write.set_tag(device, tag); device.subtag(m_write.m_tag, tag);
m_wdevice32 = func; 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_bits = 32;
m_read.m_mask = unitmask; m_read.m_mask = unitmask;
m_read.m_name = func.name(); m_read.m_name = func.name();
m_read.set_tag(device, tag); device.subtag(m_read.m_tag, tag);
m_rproto32 = func; 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_bits = 32;
m_write.m_mask = unitmask; m_write.m_mask = unitmask;
m_write.m_name = func.name(); m_write.m_name = func.name();
m_write.set_tag(device, tag); device.subtag(m_write.m_tag, tag);
m_wproto32 = func; 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_bits = 64;
m_read.m_mask = 0; m_read.m_mask = 0;
m_read.m_name = string; m_read.m_name = string;
m_read.set_tag(device, tag); device.subtag(m_read.m_tag, tag);
m_rdevice64 = func; 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_bits = 64;
m_write.m_mask = 0; m_write.m_mask = 0;
m_write.m_name = string; m_write.m_name = string;
m_write.set_tag(device, tag); device.subtag(m_write.m_tag, tag);
m_wdevice64 = func; 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_bits = 64;
m_read.m_mask = 0; m_read.m_mask = 0;
m_read.m_name = func.name(); m_read.m_name = func.name();
m_read.set_tag(device, tag); device.subtag(m_read.m_tag, tag);
m_rproto64 = func; 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_bits = 64;
m_write.m_mask = 0; m_write.m_mask = 0;
m_write.m_name = func.name(); m_write.m_name = func.name();
m_write.set_tag(device, tag); device.subtag(m_write.m_tag, tag);
m_wproto64 = func; m_wproto64 = func;
} }

View File

@ -85,17 +85,13 @@ public:
: m_type(AMH_NONE), : m_type(AMH_NONE),
m_bits(0), m_bits(0),
m_mask(0), m_mask(0),
m_name(NULL), m_name(NULL) { }
m_tag(NULL) { }
map_handler_type m_type; // type of the handler map_handler_type m_type; // type of the handler
UINT8 m_bits; // width of the handler in bits, or 0 for default UINT8 m_bits; // width of the handler in bits, or 0 for default
UINT64 m_mask; // mask for which lanes apply UINT64 m_mask; // mask for which lanes apply
const char * m_name; // name of the handler const char * m_name; // name of the handler
const char * m_tag; // tag pointing to a reference astring m_tag; // path to the target tag
astring m_derived_tag; // string used to hold derived names
void set_tag(const device_t &device, const char *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 // temporary hack until romload is update: get the driver path and support it for
// all searches // 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 // iterate over ROM sources and regions
int found = 0; int found = 0;
@ -234,49 +234,49 @@ media_auditor::summary media_auditor::audit_samples()
int found = 0; int found = 0;
// iterate over sample entries // iterate over sample entries
for (const device_t *device = m_enumerator.config().first_device(); device != NULL; device = device->next()) samples_device_iterator iter(m_enumerator.config().root_device());
if (device->type() == SAMPLES) 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()); // by default we just search using the driver name
if (intf->samplenames != NULL) 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 // starred entries indicate an additional searchpath
astring searchpath(m_enumerator.driver().name); if (intf->samplenames[sampnum][0] == '*')
// iterate over samples in this entry
for (int sampnum = 0; intf->samplenames[sampnum] != NULL; sampnum++)
{ {
// starred entries indicate an additional searchpath searchpath.cat(";").cat(&intf->samplenames[sampnum][1]);
if (intf->samplenames[sampnum][0] == '*') 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]); record.set_status(audit_record::STATUS_GOOD, audit_record::SUBSTATUS_GOOD);
continue; found++;
}
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);
} }
else
record.set_status(audit_record::STATUS_NOT_FOUND, audit_record::SUBSTATUS_NOT_FOUND);
} }
} }
} }
}
if (found == 0 && required > 0) 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 ) // load the cheat file, MESS will load a crc32.xml ( eg. 01234567.xml )
// and MAME will load gamename.xml // and MAME will load gamename.xml
device_image_interface *image = NULL; image_interface_iterator iter(machine().root_device());
for (bool gotone = machine().devicelist().first(image); gotone; gotone = image->next(image)) for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
if (image->exists()) if (image->exists())
{ {
// if we are loading through software lists, try to load shortname.xml // 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) if (strlen(m_options.software_name()) > 0)
{ {
machine_config config(*system, m_options); 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()); throw emu_fatalerror(MAMERR_FATALERROR, "Error: unknown option: %s\n", m_options.software_name());
bool found = FALSE; 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) if (list)
{ {
software_info *swinfo = software_list_find(list, m_options.software_name(), NULL); 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) if (mount == NULL || strcmp(mount,"no") != 0)
{ {
// search for an image device with the right interface // search for an image device with the right interface
const device_image_interface *image = NULL; image_interface_iterator imgiter(config.root_device());
for (bool gotone = config.devicelist().first(image); gotone; gotone = image->next(image)) for (device_image_interface *image = imgiter.first(); image != NULL; image = imgiter.next())
{ {
const char *interface = image->image_interface(); const char *interface = image->image_interface();
if (interface != NULL) if (interface != NULL)
@ -218,7 +218,7 @@ int cli_frontend::execute(int argc, char **argv)
if (strlen(option) == 0) if (strlen(option) == 0)
{ {
astring val; 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 // 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()); m_options.parse_slot_devices(argc, argv, option_errors, image->instance_name(), val.cstr());
break; break;
@ -238,7 +238,7 @@ int cli_frontend::execute(int argc, char **argv)
} }
if (!found) 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, ""); throw emu_fatalerror(MAMERR_FATALERROR, "");
} }
} }
@ -551,11 +551,8 @@ void cli_frontend::listsamples(const char *gamename)
while (drivlist.next()) while (drivlist.next())
{ {
// see if we have samples // see if we have samples
const device_t *device; samples_device_iterator iter(drivlist.config().root_device());
for (device = drivlist.config().first_device(); device != NULL; device = device->next()) if (iter.first() == NULL)
if (device->type() == SAMPLES)
break;
if (device == NULL)
continue; continue;
// print a header // 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); mame_printf_info("Samples required for driver \"%s\".\n", drivlist.driver().name);
// iterate over samples devices // iterate over samples devices
for ( ; device != NULL; device = device->next()) for (samples_device *device = iter.first(); device != NULL; device = iter.next())
if (device->type() == SAMPLES) {
{ // if the list is legit, walk it and print the sample info
// 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;
const char *const *samplenames = reinterpret_cast<const samples_interface *>(device->static_config())->samplenames; if (samplenames != NULL)
if (samplenames != NULL) for (int sampnum = 0; samplenames[sampnum] != NULL; sampnum++)
for (int sampnum = 0; samplenames[sampnum] != NULL; sampnum++) if (samplenames[sampnum][0] != '*')
if (samplenames[sampnum][0] != '*') mame_printf_info("%s\n", samplenames[sampnum]);
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); printf("Driver %s (%s):\n", drivlist.driver().name, drivlist.driver().description);
// iterate through devices // 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()); printf(" %s ('%s')", device->name(), device->tag());
@ -642,9 +639,9 @@ void cli_frontend::listslots(const char *gamename)
while (drivlist.next()) while (drivlist.next())
{ {
// iterate // iterate
const device_slot_interface *slot = NULL; slot_interface_iterator iter(drivlist.config().root_device());
bool first = true; 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 // output the line, up to the list of extensions
printf("%-13s%-10s ", first ? drivlist.driver().name : "", slot->device().tag()); 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(); const slot_interface* intf = slot->get_slot_interfaces();
for (int i = 0; intf[i].name != NULL; i++) 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(); dev->config_complete();
if (i==0) { if (i==0) {
printf("%-15s %s\n", intf[i].name,dev->name()); printf("%-15s %s\n", intf[i].name,dev->name());
@ -694,9 +691,9 @@ void cli_frontend::listmedia(const char *gamename)
while (drivlist.next()) while (drivlist.next())
{ {
// iterate // iterate
const device_image_interface *imagedev = NULL; image_interface_iterator iter(drivlist.config().root_device());
bool first = true; 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 // extract the shortname with parentheses
astring paren_shortname; astring paren_shortname;
@ -798,7 +795,7 @@ void cli_frontend::verifyroms(const char *gamename)
driver_enumerator dummy_drivlist(m_options); driver_enumerator dummy_drivlist(m_options);
dummy_drivlist.next(); dummy_drivlist.next();
machine_config &config = dummy_drivlist.config(); 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 // check if all are listed, note that empty one is included
for (int i = 0; i < m_device_count; i++) 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 // first determine the maximum number of lists we might encounter
int list_count = 0; int list_count = 0;
while (drivlist.next()) 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());
software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config(); for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next())
if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM)
list_count++; list_count++;
} }
// allocate a list // allocate a list
astring *lists = global_alloc_array(astring, list_count); astring *lists = global_alloc_array(astring, list_count);
@ -1079,28 +1076,28 @@ void cli_frontend::listsoftware(const char *gamename)
drivlist.reset(); drivlist.reset();
list_count = 0; list_count = 0;
while (drivlist.next()) 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 ) if ( list )
{ {
/* Verify if we have encountered this list before */ /* Verify if we have encountered this list before */
bool seen_before = false; bool seen_before = false;
for (int seen_index = 0; seen_index < list_count && !seen_before; seen_index++) 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; seen_before = true;
if (!seen_before) if (!seen_before)
{ {
lists[list_count++] = swlist->list_name; lists[list_count++] = swlist->list_name();
software_list_parse( list, NULL, NULL ); 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 ) ) 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) if (list_count > 0)
fprintf( out, "</softwarelists>\n" ); fprintf( out, "</softwarelists>\n" );
@ -1300,8 +1298,8 @@ void cli_frontend::execute_commands(const char *exename)
// validate? // validate?
if (strcmp(m_options.command(), CLICOMMAND_VALIDATE) == 0) if (strcmp(m_options.command(), CLICOMMAND_VALIDATE) == 0)
{ {
validate_drivers(m_options); validity_checker valid(m_options);
validate_softlists(m_options); valid.check_all();
return; return;
} }
@ -1634,10 +1632,10 @@ int media_identifier::find_by_hash(const hash_collection &hashes, int length)
} }
// next iterate over softlists // 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_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)) 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 // output information about the match
if (found) if (found)
mame_printf_info(" "); 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++; 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 ) psxcpu_device *psxcpu_device::getcpu( device_t &device, const char *cputag )
{ {
if( strcmp( cputag, DEVICE_SELF ) == 0 ) return downcast<psxcpu_device *>( device.subdevice( cputag ) );
{
return downcast<psxcpu_device *>( &device );
}
return downcast<psxcpu_device *>( device.siblingdevice( cputag ) );
} }
void psxcpu_device::irq_set( device_t &device, const char *cputag, UINT32 bitmask ) 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 ); 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 ) 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 ); 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 ) 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 ); sio->input( n_port, n_mask, n_data );
} }

View File

@ -105,10 +105,10 @@ enum
//************************************************************************** //**************************************************************************
#define MCFG_PSX_DMA_CHANNEL_READ( cputag, channel, handler ) \ #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 ) \ #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; int x;
/* find the owning CPU */ /* 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(); device_type type = cpu->type();
if (type == TMS34010 || type == TMS34020) if (type == TMS34010 || type == TMS34020)
@ -1135,7 +1136,8 @@ SCREEN_UPDATE_RGB32( tms340x0_rgb32 )
int x; int x;
/* find the owning CPU */ /* 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(); device_type type = cpu->type();
if (type == TMS34010 || type == TMS34020) 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) static void debug_command_exit(running_machine &machine)
{ {
/* turn off all traces */ /* 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); device->debug()->trace(NULL, 0, NULL);
if (cheat.length) 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 */ /* if we got a valid one, return */
device_execute_interface *exec = NULL; execute_interface_iterator iter(machine.root_device());
for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
if (cpunum-- == 0) if (cpunum-- == 0)
{ {
*result = &exec->device(); *result = &exec->device();
@ -982,8 +983,8 @@ static void execute_focus(running_machine &machine, int ref, int params, const c
cpu->debug()->ignore(false); cpu->debug()->ignore(false);
/* then loop over CPUs and set the ignore flags on all other CPUs */ /* then loop over CPUs and set the ignore flags on all other CPUs */
device_execute_interface *exec = NULL; execute_interface_iterator iter(machine.root_device());
for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
if (&exec->device() != cpu) if (&exec->device() != cpu)
exec->device().debug()->ignore(true); exec->device().debug()->ignore(true);
debug_console_printf(machine, "Now focused on CPU '%s'\n", cpu->tag()); 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; astring buffer;
/* loop over all executable devices */ /* loop over all executable devices */
device_execute_interface *exec = NULL; execute_interface_iterator iter(machine.root_device());
for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
/* build up a comma-separated list */ /* build up a comma-separated list */
if (!exec->device().debug()->observing()) 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++) for (int paramnum = 0; paramnum < params; paramnum++)
{ {
/* make sure this isn't the last live CPU */ /* make sure this isn't the last live CPU */
device_execute_interface *exec = NULL; execute_interface_iterator iter(machine.root_device());
bool gotone; bool gotone = false;
for (gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
if (&exec->device() != devicelist[paramnum] && exec->device().debug()->observing()) if (&exec->device() != devicelist[paramnum] && exec->device().debug()->observing())
{
gotone = true;
break; break;
}
if (!gotone) if (!gotone)
{ {
debug_console_printf(machine, "Can't ignore all devices!\n"); 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; astring buffer;
/* loop over all executable devices */ /* loop over all executable devices */
device_execute_interface *exec = NULL; execute_interface_iterator iter(machine.root_device());
for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
/* build up a comma-separated list */ /* build up a comma-separated list */
if (exec->device().debug()->observing()) 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 0 parameters, clear all */
if (params == 0) 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(); device->debug()->breakpoint_clear_all();
debug_console_printf(machine, "Cleared all breakpoints\n"); 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; return;
else else
{ {
device_iterator iter(machine.root_device());
bool found = false; 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)) if (device->debug()->breakpoint_clear(bpindex))
found = true; found = true;
if (found) if (found)
@ -1248,7 +1254,8 @@ static void execute_bpdisenable(running_machine &machine, int ref, int params, c
/* if 0 parameters, clear all */ /* if 0 parameters, clear all */
if (params == 0) 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); device->debug()->breakpoint_enable_all(ref);
if (ref == 0) if (ref == 0)
debug_console_printf(machine, "Disabled all breakpoints\n"); 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; return;
else else
{ {
device_iterator iter(machine.root_device());
bool found = false; 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)) if (device->debug()->breakpoint_enable(bpindex, ref))
found = true; found = true;
if (found) if (found)
@ -1284,7 +1292,8 @@ static void execute_bplist(running_machine &machine, int ref, int params, const
astring buffer; astring buffer;
/* loop over all CPUs */ /* 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) if (device->debug()->breakpoint_first() != NULL)
{ {
debug_console_printf(machine, "Device '%s' breakpoints:\n", device->tag()); 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 0 parameters, clear all */
if (params == 0) 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(); device->debug()->watchpoint_clear_all();
debug_console_printf(machine, "Cleared all watchpoints\n"); 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; return;
else else
{ {
device_iterator iter(machine.root_device());
bool found = false; 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)) if (device->debug()->watchpoint_clear(wpindex))
found = true; found = true;
if (found) if (found)
@ -1406,7 +1417,8 @@ static void execute_wpdisenable(running_machine &machine, int ref, int params, c
/* if 0 parameters, clear all */ /* if 0 parameters, clear all */
if (params == 0) 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); device->debug()->watchpoint_enable_all(ref);
if (ref == 0) if (ref == 0)
debug_console_printf(machine, "Disabled all watchpoints\n"); 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; return;
else else
{ {
device_iterator iter(machine.root_device());
bool found = false; 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)) if (device->debug()->watchpoint_enable(wpindex, ref))
found = true; found = true;
if (found) if (found)
@ -1442,7 +1455,8 @@ static void execute_wplist(running_machine &machine, int ref, int params, const
astring buffer; astring buffer;
/* loop over all CPUs */ /* 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++) for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++)
if (device->debug()->watchpoint_first(spacenum) != NULL) 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; bool cleared = false;
/* loop over CPUs and find live spots */ /* 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()) if (device->debug()->hotspot_tracking_enabled())
{ {
device->debug()->hotspot_track(0, 0); 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]; const char *filename = param[0];
int scrnum = (params > 1) ? atoi(param[1]) : 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)) 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) static void execute_images(running_machine &machine, int ref, int params, const char **param)
{ {
device_image_interface *img = NULL; image_interface_iterator iter(machine.root_device());
for (bool gotone = machine.devicelist().first(img); gotone; gotone = img->next(img)) 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]"); 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"); 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) 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; 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 (strcmp(img->brief_instance_name(),param[0])==0) {
if (img->load(param[1])==IMAGE_INIT_FAIL) { 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) 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; 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 (strcmp(img->brief_instance_name(),param[0])==0) {
img->unload(); 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 /* this can be called on exit even when no debugging is enabled, so
make sure the devdebug is valid before proceeding */ 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) if (device->debug() != NULL)
device->debug()->trace_flush(); device->debug()->trace_flush();
} }
@ -337,8 +338,9 @@ bool debug_comment_save(running_machine &machine)
xml_set_attribute(systemnode, "name", machine.system().name); xml_set_attribute(systemnode, "name", machine.system().name);
// for each device // for each device
device_iterator iter(machine.root_device());
bool found_comments = false; 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) if (device->debug()->comment_count() > 0)
{ {
// create a node for this device // 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) static void reset_transient_flags(running_machine &machine)
{ {
/* loop over CPUs and reset the transient flags */ /* 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(); device->debug()->reset_transient_flag();
machine.debugcpu_data->m_stop_when_not_device = NULL; 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) static device_t *expression_get_device(running_machine &machine, const char *tag)
{ {
device_t *device; device_iterator iter(machine.root_device());
for (device_t *device = iter.first(); device != NULL; device = iter.next())
for (device = machine.devicelist().first(); device != NULL; device = device->next())
if (mame_stricmp(device->tag(), tag) == 0) if (mame_stricmp(device->tag(), tag) == 0)
return device; return device;
@ -1630,15 +1632,8 @@ static UINT64 get_cpunum(symbol_table &table, void *ref)
running_machine &machine = *reinterpret_cast<running_machine *>(table.globalref()); running_machine &machine = *reinterpret_cast<running_machine *>(table.globalref());
device_t *target = machine.debugcpu_data->visiblecpu; device_t *target = machine.debugcpu_data->visiblecpu;
device_execute_interface *exec = NULL; execute_interface_iterator iter(machine.root_device());
int index = 0; return iter.indexof(target->execute());
for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec))
{
if (&exec->device() == target)
return index;
index++;
}
return 0;
} }

View File

@ -132,9 +132,9 @@ void debug_view_disasm::enumerate_sources()
m_source_list.reset(); m_source_list.reset();
// iterate over devices with disassembly interfaces // iterate over devices with disassembly interfaces
device_disasm_interface *dasm = NULL; disasm_interface_iterator iter(machine().root_device());
astring name; 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()); name.printf("%s '%s'", dasm->device().name(), dasm->device().tag());
m_source_list.append(*auto_alloc(machine(), debug_view_disasm_source(name, dasm->device()))); 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; astring name;
// first add all the devices' address spaces // first add all the devices' address spaces
device_memory_interface *memintf = NULL; memory_interface_iterator iter(machine().root_device());
for (bool gotone = machine().devicelist().first(memintf); gotone; gotone = memintf->next(memintf)) for (device_memory_interface *memintf = iter.first(); memintf != NULL; memintf = iter.next())
for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++) for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++)
{ {
address_space *space = memintf->space(spacenum); address_space *space = memintf->space(spacenum);

View File

@ -103,9 +103,9 @@ void debug_view_state::enumerate_sources()
m_source_list.reset(); m_source_list.reset();
// iterate over devices that have state interfaces // iterate over devices that have state interfaces
device_state_interface *state = NULL; state_interface_iterator iter(machine().root_device());
astring name; 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()); name.printf("%s '%s'", state->device().name(), state->device().tag());
m_source_list.append(*auto_alloc(machine(), debug_view_state_source(name, state->device()))); 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 *devcb_resolver::resolve_device(int index, const char *tag, device_t &current)
{ {
device_t *result = NULL; device_t *result = current.siblingdevice(tag);
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);
if (result == NULL) if (result == NULL)
throw emu_fatalerror("Unable to resolve device '%s' (requested by callback to %s '%s')", tag, current.name(), current.tag()); throw emu_fatalerror("Unable to resolve device '%s' (requested by callback to %s '%s')", tag, current.name(), current.tag());
return result; return result;

View File

@ -93,14 +93,6 @@ enum
DEVCB_TYPE_CONSTANT // constant value read 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 } #define DEVCB_NULL { DEVCB_TYPE_NULL }
// standard line or read/write handlers with the calling device passed // 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(func) { DEVCB_TYPE_DEVICE, 0, "", #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_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, DEVCB_DEVICE_SELF, NULL, #func, NULL, func, NULL } #define DEVCB_HANDLER(func) { DEVCB_TYPE_DEVICE, 0, "", #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_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 // 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_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, DEVCB_DEVICE_DRIVER, NULL, #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, 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 // 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(tag,func) { DEVCB_TYPE_DEVICE, 0, 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_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, DEVCB_DEVICE_OTHER, tag, #func, NULL, func, 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, DEVCB_DEVICE_OTHER, tag, #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL } #define DEVCB_DEVICE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL }
// constant values // constant values
#define DEVCB_CONSTANT(value) { DEVCB_TYPE_CONSTANT, value, NULL, NULL, NULL, NULL } #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 // 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) 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_execute(NULL),
m_memory(NULL), m_memory(NULL),
m_state(NULL), m_state(NULL),
m_next(NULL),
m_owner(owner),
m_interface_list(NULL),
m_type(type),
m_configured_clock(clock), 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_machine_config(mconfig),
m_static_config(NULL), m_static_config(NULL),
m_input_defaults(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_auto_finder_list(NULL),
m_machine(NULL), m_machine(NULL),
m_save(NULL), m_save(NULL),
m_tag(tag), m_basetag(tag),
m_config_complete(false) 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); 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) device_t::device_t(const machine_config &mconfig, device_type type, const char *name, const char *shortname, const char *tag, device_t *owner, UINT32 clock)
: m_debug(NULL), : m_type(type),
m_execute(NULL),
m_memory(NULL),
m_state(NULL),
m_next(NULL),
m_owner(owner),
m_interface_list(NULL),
m_type(type),
m_configured_clock(clock),
m_machine_config(mconfig),
m_static_config(NULL),
m_input_defaults(NULL),
m_name(name), m_name(name),
m_shortname(shortname), m_shortname(shortname),
m_searchpath(shortname), m_searchpath(shortname),
m_started(false), m_owner(owner),
m_clock(clock), m_next(NULL),
m_region(NULL), m_interface_list(NULL),
m_execute(NULL),
m_memory(NULL),
m_state(NULL),
m_configured_clock(clock),
m_unscaled_clock(clock), m_unscaled_clock(clock),
m_clock(clock),
m_clock_scale(1.0), m_clock_scale(1.0),
m_attoseconds_per_clock((clock == 0) ? 0 : HZ_TO_ATTOSECONDS(clock)), 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_auto_finder_list(NULL),
m_machine(NULL), m_machine(NULL),
m_save(NULL), m_save(NULL),
m_tag(tag), m_basetag(tag),
m_config_complete(false) 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); static_set_clock(*this, clock);
} }
@ -406,43 +190,9 @@ const memory_region *device_t::subregion(const char *_tag) const
if (this == NULL) if (this == NULL)
return NULL; return NULL;
// build a fully-qualified name // build a fully-qualified name and look it up
astring tempstring; astring fullpath;
return machine().region(subtag(tempstring, _tag)); return machine().region(subtag(fullpath, _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));
} }
@ -489,20 +239,14 @@ void device_t::config_complete()
// configuration has been constructed // 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 // validate via the interfaces
for (device_interface *intf = m_interface_list; intf != NULL; intf = intf->interface_next()) for (device_interface *intf = m_interface_list; intf != NULL; intf = intf->interface_next())
if (intf->interface_validity_check(options, driver)) intf->interface_validity_check(valid);
error = true;
// let the device itself validate // let the device itself validate
if (device_validity_check(options, driver)) device_validity_check(valid);
error = true;
return error;
} }
@ -780,10 +524,9 @@ void device_t::device_config_complete()
// the configuration has been constructed // 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 // do nothing by default
return false;
} }
@ -812,7 +555,6 @@ machine_config_constructor device_t::device_mconfig_additions() const
} }
//------------------------------------------------- //-------------------------------------------------
// input_ports - return a pointer to the implicit // input_ports - return a pointer to the implicit
// input ports description for this device // 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 // register_auto_finder - add a new item to the
// list of stuff to find after we go live // list of stuff to find after we go live
@ -1022,9 +915,8 @@ void device_interface::interface_config_complete()
// constructed // 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_execute_interface;
class device_memory_interface; class device_memory_interface;
class device_state_interface; class device_state_interface;
class validity_checker;
struct rom_entry; struct rom_entry;
class machine_config; class machine_config;
class emu_timer; class emu_timer;
typedef struct _input_device_default input_device_default; 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 // exception classes
class device_missing_dependencies : public emu_exception { }; 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
// device_t represents a device // device_t represents a device
@ -216,6 +138,8 @@ class device_t : public delegate_late_bind
friend class device_execute_interface; friend class device_execute_interface;
friend class simple_list<device_t>; friend class simple_list<device_t>;
friend class device_list; friend class device_list;
friend class machine_config;
friend class running_machine;
protected: protected:
// construction/destruction // construction/destruction
@ -226,12 +150,15 @@ protected:
public: public:
// getters // getters
running_machine &machine() const { assert(m_machine != NULL); return *m_machine; } 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; } device_type type() const { return m_type; }
UINT32 configured_clock() const { return m_configured_clock; }
const char *name() const { return m_name; } const char *name() const { return m_name; }
const char *shortname() const { return m_shortname; } const char *shortname() const { return m_shortname; }
const char *searchpath() const { return m_searchpath; } 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 void *static_config() const { return m_static_config; }
const machine_config &mconfig() const { return m_machine_config; } const machine_config &mconfig() const { return m_machine_config; }
const input_device_default *input_ports_defaults() const { return m_input_defaults; } 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(); } machine_config_constructor machine_config_additions() const { return device_mconfig_additions(); }
ioport_constructor input_ports() const { return device_input_ports(); } 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 // interface helpers
template<class _DeviceClass> bool interface(_DeviceClass *&intf) { intf = dynamic_cast<_DeviceClass *>(this); return (intf != NULL); } 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 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 // specialized helpers for common core interfaces
bool interface(device_execute_interface *&intf) { intf = m_execute; return (intf != NULL); } 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; } device_memory_interface &memory() const { assert(m_memory != NULL); return *m_memory; }
// owned object helpers // owned object helpers
device_t *first_subdevice() const { return m_subdevice_list.first(); }
astring &subtag(astring &dest, const char *tag) const; 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; const memory_region *subregion(const char *tag) const;
device_t *subdevice(const char *tag) const; device_t *subdevice(const char *tag) const;
device_t *siblingdevice(const char *tag) const; 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) { return downcast<_DeviceClass *>(subdevice(tag)); } template<class _DeviceClass> inline _DeviceClass *subdevice(const char *tag) const { return downcast<_DeviceClass *>(subdevice(tag)); }
template<class _DeviceClass> inline _DeviceClass *siblingdevice(const char *tag) { return downcast<_DeviceClass *>(siblingdevice(tag)); } template<class _DeviceClass> inline _DeviceClass *siblingdevice(const char *tag) const { return downcast<_DeviceClass *>(siblingdevice(tag)); }
const memory_region *region() const { return m_region; } const memory_region *region() const { return m_region; }
// configuration helpers // configuration helpers
@ -283,7 +199,7 @@ public:
// state helpers // state helpers
void config_complete(); void config_complete();
bool configured() const { return m_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; } bool started() const { return m_started; }
void reset(); void reset();
@ -328,7 +244,7 @@ protected:
virtual machine_config_constructor device_mconfig_additions() const; virtual machine_config_constructor device_mconfig_additions() const;
virtual ioport_constructor device_input_ports() const; virtual ioport_constructor device_input_ports() const;
virtual void device_config_complete(); 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_start() ATTR_COLD = 0;
virtual void device_stop() ATTR_COLD; virtual void device_stop() ATTR_COLD;
virtual void device_reset() ATTR_COLD; virtual void device_reset() ATTR_COLD;
@ -340,37 +256,37 @@ protected:
//------------------- end derived class overrides //------------------- end derived class overrides
device_debug * m_debug; // core device properties
// 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
const device_type m_type; // device type 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_name; // name of the device
astring m_shortname; // short name of the device astring m_shortname; // short name of the device
astring m_searchpath; // search path, used for media loading astring m_searchpath; // search path, used for media loading
bool m_started; // true if the start function has succeeded // device relationships
UINT32 m_clock; // device clock device_t * m_owner; // device that owns us
const memory_region * m_region; // our device-local region 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 double m_clock_scale; // clock scale factor
attoseconds_t m_attoseconds_per_clock;// period in attoseconds 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 // helper class to request auto-object discovery in the constructor of a derived class
class auto_finder_base class auto_finder_base
{ {
@ -480,11 +396,19 @@ protected:
auto_finder_base * m_auto_finder_list; auto_finder_base * m_auto_finder_list;
private: 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 // private state; accessor use required
running_machine * m_machine; running_machine * m_machine;
save_manager * m_save; 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_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 // optional operation overrides
virtual void interface_config_complete(); 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_pre_start();
virtual void interface_post_start(); virtual void interface_post_start();
virtual void interface_pre_reset(); 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 // 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 // subdevice - given a tag, find the device by
// with the given interface // name relative to this device
//------------------------------------------------- //-------------------------------------------------
template<class _InterfaceClass> inline device_t *device_t::subdevice(const char *tag) const
bool device_list::first(_InterfaceClass *&intf) const
{ {
for (device_t *cur = super::first(); cur != NULL; cur = cur->next()) // safety first
if (cur->interface(intf)) if (this == NULL)
return true; return NULL;
return false;
// 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()) if (!basetype::isnull())
{ {
device_t *device = (m_device_name == NULL) ? &search_root : search_root.subdevice(m_device_name); 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()); 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); 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 // 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)); device_validity_check_func validity_func = reinterpret_cast<device_validity_check_func>(get_legacy_fct(DEVINFO_FCT_VALIDITY_CHECK));
if (validity_func != NULL) if (validity_func != NULL)
return (*validity_func)(&driver, this, options); (*validity_func)(&mconfig().gamedrv(), this, mconfig().options());
return false;
} }
@ -239,7 +238,7 @@ void legacy_device_base::device_reset()
void legacy_device_base::device_stop() 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)); device_stop_func stop_func = reinterpret_cast<device_stop_func>(get_legacy_fct(DEVINFO_FCT_STOP));
if (stop_func != NULL) 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 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 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 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_start();
virtual void device_reset(); virtual void device_reset();
virtual void device_stop(); 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; 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__ */ #endif /* __DIDISASM_H__ */

View File

@ -484,37 +484,22 @@ void device_execute_interface::execute_set_input(int linenum, int state)
// constructed // 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 (m_vblank_interrupt != NULL)
{ {
if (device().mconfig().devicelist().count(SCREEN) == 0) screen_device_iterator iter(device().mconfig().root_device());
{ if (iter.first() == NULL)
mame_printf_error("%s: %s device '%s' has a VBLANK interrupt, but the driver is screenless!\n", driver.source_file, driver.name, device().tag()); mame_printf_error("VBLANK interrupt specified, but the driver is screenless\n");
error = true; 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);
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;
}
} }
if (m_timed_interrupt != NULL && m_timed_interrupt_period == attotime::zero) if (m_timed_interrupt != NULL && m_timed_interrupt_period == attotime::zero)
{ mame_printf_error("Timed interrupt handler specified with 0 period\n");
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;
}
else if (m_timed_interrupt == NULL && m_timed_interrupt_period != attotime::zero) else if (m_timed_interrupt == NULL && m_timed_interrupt_period != attotime::zero)
{ mame_printf_error("No timer interrupt handler specified, but has a non-0 period given\n");
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;
} }
@ -526,7 +511,8 @@ bool device_execute_interface::interface_validity_check(emu_options &options, co
void device_execute_interface::interface_pre_start() void device_execute_interface::interface_pre_start()
{ {
// fill in the initial states // 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_suspend = SUSPEND_REASON_RESET;
m_profiler = profile_type(index + PROFILER_DEVICE_FIRST); m_profiler = profile_type(index + PROFILER_DEVICE_FIRST);
m_inttrigger = index + TRIGGER_INT; 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); m_timedint_timer = device().machine().scheduler().timer_alloc(FUNC(static_trigger_periodic_interrupt), (void *)this);
// register for save states // register for save states
m_device.save_item(NAME(m_suspend)); device().save_item(NAME(m_suspend));
m_device.save_item(NAME(m_nextsuspend)); device().save_item(NAME(m_nextsuspend));
m_device.save_item(NAME(m_eatcycles)); device().save_item(NAME(m_eatcycles));
m_device.save_item(NAME(m_nexteatcycles)); device().save_item(NAME(m_nexteatcycles));
m_device.save_item(NAME(m_trigger)); device().save_item(NAME(m_trigger));
m_device.save_item(NAME(m_totalcycles)); device().save_item(NAME(m_totalcycles));
m_device.save_item(NAME(m_localtime)); device().save_item(NAME(m_localtime));
} }
@ -627,7 +613,7 @@ void device_execute_interface::interface_post_reset()
void device_execute_interface::interface_clock_changed() void device_execute_interface::interface_clock_changed()
{ {
// recompute cps and spc // 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); m_attoseconds_per_cycle = HZ_TO_ATTOSECONDS(m_cycles_per_second);
// update the device's divisor // 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 // get the default vector and acknowledge the interrupt if needed
int vector = m_input[irqline].default_irq_callback(); 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 there's a driver callback, run it to get the vector
if (m_driver_irq != NULL) if (m_driver_irq != NULL)
vector = (*m_driver_irq)(&m_device, irqline); vector = (*m_driver_irq)(&device(), irqline);
// notify the debugger // notify the debugger
debugger_interrupt_hook(&m_device, irqline); debugger_interrupt_hook(&device(), irqline);
return vector; return vector;
} }
@ -682,7 +668,7 @@ attoseconds_t device_execute_interface::minimum_quantum() const
// if we don't have that information, compute it // if we don't have that information, compute it
attoseconds_t basetick = m_attoseconds_per_cycle; attoseconds_t basetick = m_attoseconds_per_cycle;
if (basetick == 0) 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 // apply the minimum cycle count
return basetick * min_cycles(); return basetick * min_cycles();
@ -714,9 +700,10 @@ void device_execute_interface::on_vblank(screen_device &screen, bool vblank_stat
// generate the interrupt callback // generate the interrupt callback
if (!suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE)) 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 // static_trigger_periodic_interrupt - timer
// callback for timed interrupts // callback for timed interrupts
@ -731,7 +718,7 @@ void device_execute_interface::trigger_periodic_interrupt()
{ {
// bail if there is no routine // bail if there is no routine
if (m_timed_interrupt != NULL && !suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE)) 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) void device_execute_interface::device_input::start(device_execute_interface *execute, int linenum)
{ {
m_execute = execute; m_execute = execute;
m_device = &m_execute->m_device; m_device = &m_execute->device();
m_linenum = linenum; m_linenum = linenum;
reset(); reset();

View File

@ -228,7 +228,7 @@ protected:
virtual void execute_set_input(int linenum, int state); virtual void execute_set_input(int linenum, int state);
// interface-level overrides // 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_pre_start();
virtual void interface_post_start(); virtual void interface_post_start();
virtual void interface_pre_reset(); virtual void interface_pre_reset();
@ -322,6 +322,9 @@ private:
attoseconds_t minimum_quantum() const; 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() void device_image_interface::update_names()
{ {
const device_image_interface *image = NULL; image_interface_iterator iter(device().mconfig().root_device());
int count = 0; int count = iter.count();
int index = -1; int index = iter.indexof(*this);
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++;
}
if (count > 1) { if (count > 1) {
m_instance_name.printf("%s%d", device_typename(image_type()), index + 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); 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; image = _image;
slc = 0; sld = 0;
swi = image->software_entry(); swi = image->software_entry();
swp = image->part_entry(); swp = image->part_entry();
@ -1220,8 +1212,8 @@ void ui_menu_control_device_image::handle()
} }
case START_SOFTLIST: case START_SOFTLIST:
slc = 0; sld = 0;
ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software(machine(), container, image->image_interface(), &slc))); ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software(machine(), container, image->image_interface(), &sld)));
state = SELECT_SOFTLIST; state = SELECT_SOFTLIST;
break; break;
@ -1233,17 +1225,17 @@ void ui_menu_control_device_image::handle()
} }
case SELECT_SOFTLIST: case SELECT_SOFTLIST:
if(!slc) { if(!sld) {
ui_menu::stack_pop(machine()); ui_menu::stack_pop(machine());
break; break;
} }
software_info_name = ""; 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; state = SELECT_PARTLIST;
break; break;
case SELECT_PARTLIST: 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); swi = software_list_find(swl, software_info_name, NULL);
if(swinfo_has_multiple_parts(swi, image->image_interface())) { if(swinfo_has_multiple_parts(swi, image->image_interface())) {
submenu_result = -1; submenu_result = -1;

View File

@ -324,6 +324,9 @@ protected:
bool m_is_loading; bool m_is_loading;
}; };
// iterator
typedef device_interface_iterator<device_image_interface> image_interface_iterator;
class ui_menu_control_device_image : public ui_menu { class ui_menu_control_device_image : public ui_menu {
public: public:
ui_menu_control_device_image(running_machine &machine, render_container *container, device_image_interface *image); ui_menu_control_device_image(running_machine &machine, render_container *container, device_image_interface *image);
@ -344,10 +347,10 @@ protected:
int submenu_result; int submenu_result;
bool create_confirmed; bool create_confirmed;
bool softlist_done; bool softlist_done;
const class software_list *swl; const struct software_list *swl;
const class software_info *swi; const software_info *swi;
const class software_part *swp; const software_part *swp;
const class software_list_config *slc; const class software_list_device *sld;
astring software_info_name; astring software_info_name;
void test_create(bool &can_create, bool &need_confirm); 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 // 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 detected_overlap = DETECT_OVERLAPPING_MEMORY ? false : true;
bool error = false;
// loop over all address spaces // loop over all address spaces
for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++) 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 // validate the global map parameters
if (map->m_spacenum != spacenum) if (map->m_spacenum != spacenum)
{ mame_printf_error("Space %d has address space %d handlers!\n", spacenum, map->m_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;
}
if (map->m_databits != datawidth) if (map->m_databits != datawidth)
{ mame_printf_error("Wrong memory handlers provided for %s space! (width = %d, memory = %08x)\n", spaceconfig->m_name, datawidth, map->m_databits);
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;
}
// loop over entries and look for errors // loop over entries and look for errors
for (address_map_entry *entry = map->m_entrylist.first(); entry != NULL; entry = entry->next()) 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_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))) (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; detected_overlap = true;
break; break;
} }
@ -286,17 +279,11 @@ bool device_memory_interface::interface_validity_check(emu_options &options, con
// look for inverted start/end pairs // look for inverted start/end pairs
if (byteend < bytestart) if (byteend < bytestart)
{ mame_printf_error("Wrong %s memory read handler start = %08x > end = %08x\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend);
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;
}
// look for misaligned entries // look for misaligned entries
if ((bytestart & (alignunit - 1)) != 0 || (byteend & (alignunit - 1)) != (alignunit - 1)) if ((bytestart & (alignunit - 1)) != 0 || (byteend & (alignunit - 1)) != (alignunit - 1))
{ 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);
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;
}
// if this is a program space, auto-assign implicit ROM entries // if this is a program space, auto-assign implicit ROM entries
if (entry->m_read.m_type == AMH_ROM && entry->m_region == NULL) 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 this entry references a memory region, validate it
if (entry->m_region != NULL && entry->m_share == 0) 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; bool found = false;
for (const rom_source *source = rom_first_source(device().mconfig()); source != NULL && !found; source = rom_next_source(*source)) astring entry_region;
for (const rom_entry *romp = rom_first_region(*source); !ROMENTRY_ISEND(romp) && !found; romp++) device().siblingtag(entry_region, entry->m_region);
{
const char *regiontag_c = ROMREGION_GETTAG(romp);
if (regiontag_c != NULL)
{
astring fulltag;
astring regiontag;
// a leading : on a region name indicates an absolute region, so fix up accordingly // look for the region
if (entry->m_region[0] == ':') 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))
regiontag = &entry->m_region[1]; {
} astring fulltag;
else rom_region_name(fulltag, &device().mconfig().gamedrv(), source, romp);
{ if (fulltag == entry_region)
if (strchr(entry->m_region,':')) { {
regiontag = entry->m_region; // verify the address range is within the region's bounds
} else { offs_t length = ROMREGION_GETLENGTH(romp);
device().siblingtag(regiontag, entry->m_region); 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;
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;
}
} }
} }
// error if not found // error if not found
if (!found) if (!found)
{ 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);
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;
}
} }
// make sure all devices exist // 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) || if (entry->m_read.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_read.m_tag && device().siblingdevice(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 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: %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); mame_printf_error("%s space memory map entry references nonexistant device '%s'\n", spaceconfig->m_name, entry->m_write.m_tag.cstr());
error = true;
}
// make sure ports exist // 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) || // 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)) // (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 space memory map entry references nonexistant port tag '%s'\n", spaceconfig->m_name, entry->m_read.m_tag.cstr());
// 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;
// }
// validate bank and share tags // validate bank and share tags
if (entry->m_read.m_type == AMH_BANK && !validate_tag(driver, "bank", entry->m_read.m_tag)) if (entry->m_read.m_type == AMH_BANK)
error = true ; valid.validate_tag(entry->m_read.m_tag);
if (entry->m_write.m_type == AMH_BANK && !validate_tag(driver, "bank", entry->m_write.m_tag)) if (entry->m_write.m_type == AMH_BANK)
error = true; valid.validate_tag(entry->m_write.m_tag);
if (entry->m_share != NULL && !validate_tag(driver, "share", entry->m_share)) if (entry->m_share != NULL)
error = true; valid.validate_tag(entry->m_share);
} }
// release the address map // release the address map
global_free(map); global_free(map);
} }
} }
return error;
} }

View File

@ -134,13 +134,16 @@ protected:
virtual bool memory_readop(offs_t offset, int size, UINT64 &value); virtual bool memory_readop(offs_t offset, int size, UINT64 &value);
// interface-level overrides // 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 // configuration
address_map_constructor m_address_map[ADDRESS_SPACES]; // address maps for each address space address_map_constructor m_address_map[ADDRESS_SPACES]; // address maps for each address space
address_space * m_addrspace[ADDRESS_SPACES]; // reported address spaces 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; class netdev *m_dev;
int m_intf; int m_intf;
}; };
// iterator
typedef device_interface_iterator<device_network_interface> network_interface_iterator;
#endif #endif

View File

@ -74,5 +74,8 @@ protected:
virtual void nvram_write(emu_file &file) = 0; virtual void nvram_write(emu_file &file) = 0;
}; };
// iterator
typedef device_interface_iterator<device_nvram_interface> nvram_interface_iterator;
#endif /* __DINVRAM_H__ */ #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); 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 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; }; 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 device_list &devlist, emu_options &options) const { return NULL; }; 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; } const input_device_default *input_ports_defaults() const { return m_input_defaults; }
device_t* get_card_device(); device_t* get_card_device();
protected: protected:
@ -58,6 +58,9 @@ protected:
const slot_interface *m_slot_interfaces; const slot_interface *m_slot_interfaces;
}; };
// iterator
typedef device_interface_iterator<device_slot_interface> slot_interface_iterator;
// ======================> device_slot_card_interface // ======================> device_slot_card_interface
class device_slot_card_interface : public device_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 // 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 // loop over all the routes
for (const sound_route *route = first_route(); route != NULL; route = route->next()) for (const sound_route *route = first_route(); route != NULL; route = route->next())
{ {
// find a device with the requested tag // 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) if (target == NULL)
{ mame_printf_error("Attempting to route sound to non-existant device '%s'\n", route->m_target.cstr());
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;
}
// if it's not a speaker or a sound device, error // if it's not a speaker or a sound device, error
const device_sound_interface *sound; const device_sound_interface *sound;
if (target != NULL && target->type() != SPEAKER && !target->interface(sound)) if (target != NULL && target->type() != SPEAKER && !target->interface(sound))
{ mame_printf_error("Attempting to route sound to a non-sound device '%s' (%s)\n", route->m_target.cstr(), target->name());
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;
}
} }
return error;
} }
@ -267,8 +258,8 @@ bool device_sound_interface::interface_validity_check(emu_options &options, cons
void device_sound_interface::interface_pre_start() void device_sound_interface::interface_pre_start()
{ {
// scan all the sound devices // scan all the sound devices
device_sound_interface *sound = NULL; sound_interface_iterator iter(m_device.machine().root_device());
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 // scan each route on the device
for (const sound_route *route = sound->first_route(); route != NULL; route = route->next()) 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 // now iterate through devices again and assign any auto-allocated inputs
m_auto_allocated_inputs = 0; 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 // scan each route on the device
for (const sound_route *route = sound->first_route(); route != NULL; route = route->next()) 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() void device_sound_interface::interface_post_start()
{ {
// iterate over all the sound devices // iterate over all the sound devices
device_sound_interface *sound = NULL; sound_interface_iterator iter(m_device.machine().root_device());
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 // scan each route on the device
for (const sound_route *route = sound->first_route(); route != NULL; route = route->next()) for (const sound_route *route = sound->first_route(); route != NULL; route = route->next())

View File

@ -138,7 +138,7 @@ public:
protected: protected:
// optional operation overrides // 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_pre_start();
virtual void interface_post_start(); virtual void interface_post_start();
virtual void interface_pre_reset(); virtual void interface_pre_reset();
@ -149,5 +149,7 @@ protected:
int m_auto_allocated_inputs; // number of auto-allocated inputs targeting us 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__ */ #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); assert(symbol != NULL);
// allocate new entry // 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 // append to the end of the list
m_state_list.append(*entry); m_state_list.append(*entry);

View File

@ -195,6 +195,9 @@ protected:
// fast access to common entries // 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 // iterate through all slot devices
options_entry entry[2] = { { 0 }, { 0 } }; options_entry entry[2] = { { 0 }, { 0 } };
bool first = true; bool first = true;
const device_slot_interface *slot = NULL;
// create the configuration // create the configuration
machine_config config(*cursystem, *this); machine_config config(*cursystem, *this);
bool added = false; 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 // first device? add the header as to be pretty
if (first && isfirst) if (first && isfirst)
@ -253,7 +253,7 @@ bool emu_options::add_slot_options(bool isfirst)
entry[0].name = slot->device().tag(); entry[0].name = slot->device().tag();
entry[0].description = NULL; entry[0].description = NULL;
entry[0].flags = OPTION_STRING | OPTION_FLAG_DEVICE; 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); add_entries(entry, true);
added = true; added = true;
@ -275,10 +275,10 @@ void emu_options::update_slot_options()
return; return;
// iterate through all slot devices // iterate through all slot devices
const device_slot_interface *slot = NULL;
// create the configuration // create the configuration
machine_config config(*cursystem, *this); 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 // retrieve info about the device instance
astring option_name; astring option_name;
@ -286,7 +286,7 @@ void emu_options::update_slot_options()
if (exists(slot->device().tag())) { if (exists(slot->device().tag())) {
if (slot->get_slot_interfaces() != NULL) { 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); 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 } }; options_entry entry[2] = { { 0 }, { 0 } };
bool first = true; bool first = true;
// iterate through all image devices // iterate through all image devices
const device_image_interface *image = NULL;
machine_config config(*cursystem, *this); 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 // first device? add the header as to be pretty
if (first && isfirst) if (first && isfirst)
@ -438,7 +438,8 @@ void emu_options::parse_standard_inis(astring &error_string)
// parse "vector.ini" for vector games // parse "vector.ini" for vector games
{ {
machine_config config(*cursystem, *this); 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) if (device->screen_type() == SCREEN_TYPE_VECTOR)
{ {
parse_one_ini("vector", OPTION_PRIORITY_VECTOR_INI, &error_string); 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; xml_data_node *node;
const char *dev_instance; const char *dev_instance;
const char *working_directory; const char *working_directory;
device_image_interface *image = NULL;
if ((config_type == CONFIG_TYPE_GAME) && (parentnode != 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')) 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())) { if (!strcmp(dev_instance, image->instance_name())) {
working_directory = xml_get_attribute_string(node, "directory", NULL); 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; xml_data_node *node;
const char *dev_instance; const char *dev_instance;
device_image_interface *image = NULL;
/* only care about game-specific data */ /* only care about game-specific data */
if (config_type == CONFIG_TYPE_GAME) 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(); 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 */ no need to assert in case they are missing */
{ {
int index = 0; 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(); const char *filename = image->filename();
@ -186,12 +186,11 @@ static void image_options_extract(running_machine &machine)
void image_unload_all(running_machine &machine) void image_unload_all(running_machine &machine)
{ {
device_image_interface *image = NULL;
// extract the options // extract the options
image_options_extract(machine); 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 // unload this image
image->unload(); image->unload();
@ -205,10 +204,10 @@ void image_unload_all(running_machine &machine)
void image_device_init(running_machine &machine) void image_device_init(running_machine &machine)
{ {
const char *image_name; const char *image_name;
device_image_interface *image = NULL;
/* make sure that any required devices have been allocated */ /* 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 */ /* is an image specified for this image */
image_name = machine.options().device_option(*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 */ /* is an image specified for this image */
image_name = image->filename(); image_name = image->filename();
@ -264,10 +263,9 @@ void image_device_init(running_machine &machine)
void image_postdevice_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 */ /* 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(); int result = image->finish_load();
/* did the image load fail? */ /* 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) astring &image_info_astring(running_machine &machine, astring &string)
{ {
device_image_interface *image = NULL;
string.printf("%s\n\n", machine.system().description); string.printf("%s\n\n", machine.system().description);
#if 0 #if 0
@ -385,7 +381,8 @@ astring &image_info_astring(running_machine &machine, astring &string)
} }
#endif #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(); const char *name = image->filename();
if (name != NULL) 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_from_absolute_index(running_machine &machine, int absolute_index)
{ {
device_image_interface *image = NULL; image_interface_iterator iter(machine.root_device());
int cnt = 0; return iter.byindex(absolute_index);
/* 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;
} }
/*------------------------------------------------- /*-------------------------------------------------

View File

@ -163,4 +163,7 @@ private:
// device type definition // device type definition
extern const device_type BITBANGER; extern const device_type BITBANGER;
// device iterator
typedef device_type_iterator<&device_creator<bitbanger_device>, bitbanger_device> bitbanger_device_iterator;
#endif /* __BITBNGR_H__ */ #endif /* __BITBNGR_H__ */

View File

@ -336,7 +336,7 @@ void cassette_image_device::call_display()
int n; int n;
double position, length; double position, length;
cassette_state uistate; cassette_state uistate;
device_t *dev; cassette_image_device *dev;
static const UINT8 shapes[8] = { 0x2d, 0x5c, 0x7c, 0x2f, 0x2d, 0x20, 0x20, 0x20 }; static const UINT8 shapes[8] = { 0x2d, 0x5c, 0x7c, 0x2f, 0x2d, 0x20, 0x20, 0x20 };
/* abort if we should not be showing the image */ /* abort if we should not be showing the image */
@ -354,13 +354,9 @@ void cassette_image_device::call_display()
x = 0.2f; x = 0.2f;
y = 0.5f; y = 0.5f;
dev = device().machine().devicelist().first(CASSETTE ); cassette_device_iterator iter(device().machine().root_device());
for (dev = iter.first(); dev != NULL && strcmp( dev->tag(), device().tag() ); dev = iter.next())
while ( dev && strcmp( dev->tag(), device().tag() ) )
{
y += 1; y += 1;
dev = dev->typenext();
}
y *= ui_get_line_height(device().machine()) + 2.0f * UI_BOX_TB_BORDER; y *= ui_get_line_height(device().machine()) + 2.0f * UI_BOX_TB_BORDER;
/* choose which frame of the animation we are at */ /* choose which frame of the animation we are at */

View File

@ -113,6 +113,9 @@ private:
// device type definition // device type definition
extern const device_type CASSETTE; 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 DEVICE CONFIGURATION MACROS
***************************************************************************/ ***************************************************************************/

View File

@ -266,13 +266,13 @@ void info_xml_creator::output_devices()
m_drivlist.reset(); m_drivlist.reset();
m_drivlist.next(); m_drivlist.next();
machine_config &config = m_drivlist.config(); 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 // check if all are listed, note that empty one is included
bool display_all = driver_list::total() == (m_drivlist.count()+1); bool display_all = driver_list::total() == (m_drivlist.count()+1);
for(int i=0;i<m_device_count;i++) { for(int i=0;i<m_device_count;i++) {
if (display_all || (m_device_used[i]!=0)) { if (display_all || (m_device_used[i]!=0)) {
device_type type = *s_devices_sorted[i]; 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(); dev->config_complete();
// print the header and the game name // print the header and the game name
@ -311,7 +311,8 @@ void info_xml_creator::output_one()
machine_config &config = m_drivlist.config(); machine_config &config = m_drivlist.config();
ioport_list portlist; ioport_list portlist;
astring errors; 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); input_port_list_init(*device, portlist, errors);
// print the header and the game name // print the header and the game name
@ -407,7 +408,8 @@ void info_xml_creator::output_device_roms()
void info_xml_creator::output_sampleof() void info_xml_creator::output_sampleof()
{ {
// iterate over sample devices // 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; const char *const *samplenames = ((const samples_interface *)device->static_config())->samplenames;
if (samplenames != NULL) if (samplenames != NULL)
@ -566,7 +568,8 @@ void info_xml_creator::output_rom(const rom_source *source)
void info_xml_creator::output_sample() void info_xml_creator::output_sample()
{ {
// iterate over sample devices // 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; const char *const *samplenames = ((const samples_interface *)device->static_config())->samplenames;
if (samplenames != NULL) if (samplenames != NULL)
@ -602,8 +605,8 @@ void info_xml_creator::output_sample()
void info_xml_creator::output_chips() void info_xml_creator::output_chips()
{ {
// iterate over executable devices // iterate over executable devices
device_execute_interface *exec = NULL; execute_interface_iterator execiter(m_drivlist.config().root_device());
for (bool gotone = m_drivlist.config().devicelist().first(exec); gotone; gotone = exec->next(exec)) for (device_execute_interface *exec = execiter.first(); exec != NULL; exec = execiter.next())
{ {
fprintf(m_output, "\t\t<chip"); fprintf(m_output, "\t\t<chip");
fprintf(m_output, " type=\"cpu\""); fprintf(m_output, " type=\"cpu\"");
@ -614,8 +617,8 @@ void info_xml_creator::output_chips()
} }
// iterate over sound devices // iterate over sound devices
device_sound_interface *sound = NULL; sound_interface_iterator sounditer(m_drivlist.config().root_device());
for (bool gotone = m_drivlist.config().devicelist().first(sound); gotone; gotone = sound->next(sound)) for (device_sound_interface *sound = sounditer.first(); sound != NULL; sound = sounditer.next())
{ {
fprintf(m_output, "\t\t<chip"); fprintf(m_output, "\t\t<chip");
fprintf(m_output, " type=\"audio\""); fprintf(m_output, " type=\"audio\"");
@ -636,7 +639,8 @@ void info_xml_creator::output_chips()
void info_xml_creator::output_display() void info_xml_creator::output_display()
{ {
// iterate over screens // 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"); fprintf(m_output, "\t\t<display");
@ -714,11 +718,12 @@ void info_xml_creator::output_display()
void info_xml_creator::output_sound() 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 // if we have no sound, zero m_output the speaker count
const device_sound_interface *sound = NULL; sound_interface_iterator snditer(m_drivlist.config().root_device());
if (!m_drivlist.config().devicelist().first(sound)) if (snditer.first() == NULL)
speakers = 0; speakers = 0;
fprintf(m_output, "\t\t<sound channels=\"%d\"/>\n", speakers); 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() void info_xml_creator::output_images()
{ {
const device_image_interface *dev = NULL; image_interface_iterator iter(m_drivlist.config().root_device());
for (bool gotone = m_drivlist.config().devicelist().first(dev); gotone; gotone = dev->next(dev)) for (const device_image_interface *dev = iter.first(); dev != NULL; dev = iter.next())
{ {
// print m_output device type // print m_output device type
fprintf(m_output, "\t\t<device type=\"%s\"", xml_normalize_string(dev->image_type_name())); 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() void info_xml_creator::output_slots()
{ {
const device_slot_interface *slot = NULL; slot_interface_iterator iter(m_drivlist.config().root_device());
for (bool gotone = m_drivlist.config().devicelist().first(slot); gotone; gotone = slot->next(slot)) for (const device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next())
{ {
// print m_output device type // print m_output device type
fprintf(m_output, "\t\t<slot name=\"%s\">\n", xml_normalize_string(slot->device().tag())); 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, "\t\t\t<slotoption");
fprintf(m_output, " name=\"%s\"", xml_normalize_string(intf[i].name)); 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, " default=\"yes\"");
} }
fprintf(m_output, "/>\n"); fprintf(m_output, "/>\n");
@ -1230,13 +1235,13 @@ void info_xml_creator::output_slots()
void info_xml_creator::output_software_list() 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, "\t\t<softwarelist name=\"%s\" ", swlist->list_name); fprintf(m_output, "status=\"%s\" ", (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) ? "original" : "compatible");
fprintf(m_output, "status=\"%s\" ", (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) ? "original" : "compatible"); if (swlist->filter()) {
if (swlist->filter) { fprintf(m_output, "filter=\"%s\" ", swlist->filter());
fprintf(m_output, "filter=\"%s\" ", swlist->filter);
} }
fprintf(m_output, "/>\n"); fprintf(m_output, "/>\n");
} }
@ -1251,10 +1256,9 @@ void info_xml_creator::output_software_list()
void info_xml_creator::output_ramoptions() 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()); fprintf(m_output, "\t\t<ramoption default=\"1\">%u</ramoption>\n", ram->default_size());
if (ram->extra_options() != NULL) if (ram->extra_options() != NULL)

View File

@ -903,7 +903,8 @@ time_t input_port_init(running_machine &machine)
init_port_types(machine); init_port_types(machine);
/* if we have a token list, proceed */ /* 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; astring errors;
input_port_list_init(*device, machine.m_portlist, 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 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; astring fullpath;
const input_port_config *port = device->machine().port(device->subtag(tempstring, tag)); const input_port_config *port = device.machine().port(device.subtag(fullpath, tag));
if (port == NULL) if (port == NULL)
fatalerror("Unable to locate input port '%s'", tag); fatalerror("Unable to locate input port '%s'", tag);
return input_port_read_direct(port); 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 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; 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 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) static void init_port_state(running_machine &machine)
{ {
const char *joystick_map_default = machine.options().joystick_map(); const char *joystick_map_default = machine.options().joystick_map();
@ -2012,7 +1999,7 @@ static void init_port_state(running_machine &machine)
astring devicetag; astring devicetag;
if (!field->read.isnull()) 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); field->read.late_bind(*(*readdevicetail)->device);
readdevicetail = &(*readdevicetail)->next; 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 this entry has device output, allocate memory for the tracking structure */
if (!field->write.isnull()) 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); field->write.late_bind(*(*writedevicetail)->device);
writedevicetail = &(*writedevicetail)->next; 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 this entry has device output, allocate memory for the tracking structure */
if (!field->crossmapper.isnull()) 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); 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) UINT32 port_default_value(const char *fulltag, UINT32 mask, UINT32 defval, device_t &owner)
{ {
astring tempstring; const input_device_default *def = owner.input_ports_defaults();
const input_device_default *def = NULL; if (def != NULL)
def = owner.input_ports_defaults(); {
if (def!=NULL) { astring fullpath;
while (def->tag!=NULL) { for ( ; def->tag != NULL; def++)
if ((strcmp(fulltag,owner.subtag(tempstring,def->tag))==0) && (def->mask == mask)) { if (owner.subtag(fullpath, def->tag) == fulltag && def->mask == mask)
return def->defvalue; return def->defvalue;
}
def++;
}
} }
return defval; return defval;
} }
@ -4830,6 +4814,7 @@ input_port_config *ioconfig_alloc_port(ioport_list &portlist, device_t &device,
{ {
astring fulltag; astring fulltag;
device.subtag(fulltag, tag); device.subtag(fulltag, tag);
mame_printf_verbose("ioport '%s' created\n", fulltag.cstr());
return &portlist.append(fulltag, *global_alloc(input_port_config(device, fulltag))); 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); input_port_value input_port_read(running_machine &machine, const char *tag);
/* return the value of a device input port specified by 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 */ /* 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); 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), memory_data(NULL),
palette_data(NULL), palette_data(NULL),
romload_data(NULL), romload_data(NULL),
input_data(NULL),
input_port_data(NULL), input_port_data(NULL),
ui_input_data(NULL), ui_input_data(NULL),
debugcpu_data(NULL), debugcpu_data(NULL),
@ -171,7 +170,6 @@ running_machine::running_machine(const machine_config &_config, osd_interface &o
m_video(NULL), m_video(NULL),
m_tilemap(NULL), m_tilemap(NULL),
m_debug_view(NULL), m_debug_view(NULL),
m_driver_device(NULL),
m_current_phase(MACHINE_PHASE_PREINIT), m_current_phase(MACHINE_PHASE_PREINIT),
m_paused(false), m_paused(false),
m_hard_reset_pending(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)); memset(&m_base_time, 0, sizeof(m_base_time));
// set the machine on all devices // set the machine on all devices
const_cast<device_list &>(devicelist()).set_machine_all(*this); device_iterator iter(root_device());
for (device_t *device = iter.first(); device != NULL; device = iter.next())
// find the driver device config and tell it which game device->set_machine(*this);
m_driver_device = device<driver_device>("root");
if (m_driver_device == NULL)
throw emu_fatalerror("Machine configuration missing driver_device");
// find devices // find devices
primary_screen = downcast<screen_device *>(devicelist().first(SCREEN)); for (device_t *device = iter.first(); device != NULL; device = iter.next())
for (device_t *device = devicelist().first(); device != NULL; device = device->next())
if (dynamic_cast<cpu_device *>(device) != NULL) if (dynamic_cast<cpu_device *>(device) != NULL)
{ {
firstcpu = downcast<cpu_device *>(device); firstcpu = downcast<cpu_device *>(device);
break; break;
} }
screen_device_iterator screeniter(root_device());
primary_screen = screeniter.first();
// fetch core options // fetch core options
if (options().debug()) if (options().debug())
@ -318,8 +314,12 @@ void running_machine::start()
// so this location in the init order is important // so this location in the init order is important
ui_set_startup_text(*this, "Initializing...", true); ui_set_startup_text(*this, "Initializing...", true);
// start up the devices // register callbacks for the devices, then start them
const_cast<device_list &>(devicelist()).start_all(); 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 // if we're coming in with a savegame request, process it now
const char *savegame = options().state(); 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) device_t &running_machine::add_dynamic_device(device_t &owner, device_type type, const char *tag, UINT32 clock)
{ {
// allocate and append this device // add the device in a standard manner
astring fulltag; device_t *device = const_cast<machine_config &>(m_config).device_add(&owner, tag, type, clock);
owner.subtag(fulltag, tag);
device_t &device = const_cast<device_list &>(devicelist()).append(fulltag, *type(m_config, fulltag, &owner, clock));
// append any machine config additions from new devices // notify this device and all its subdevices that they are now configured
for (device_t *curdevice = devicelist().first(); curdevice != NULL; curdevice = curdevice->next()) device_iterator iter(root_device());
if (!curdevice->configured()) for (device_t *device = iter.first(); device != NULL; device = iter.next())
{ if (!device->configured())
machine_config_constructor machconfig = curdevice->machine_config_additions(); device->config_complete();
if (machconfig != NULL) return *device;
(*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;
} }
@ -633,6 +623,7 @@ void running_machine::resume()
memory_region *running_machine::region_alloc(const char *name, UINT32 length, UINT8 width, endianness_t endian) 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 // 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); memory_region *info = m_regionlist.find(name);
if (info != NULL) if (info != NULL)
@ -887,6 +878,115 @@ void running_machine::logfile_callback(running_machine &machine, const char *buf
machine.m_logfile->puts(buffer); 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 MEMORY REGIONS
***************************************************************************/ ***************************************************************************/
@ -1143,8 +1243,10 @@ ioport_constructor driver_device::device_input_ports() const
void driver_device::device_start() void driver_device::device_start()
{ {
// reschedule ourselves to be last // reschedule ourselves to be last
if (next() != NULL) device_iterator iter(*this);
throw device_missing_dependencies(); 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 // call the game-specific init
if (m_system->driver_init != NULL) if (m_system->driver_init != NULL)

View File

@ -186,7 +186,6 @@ class osd_interface;
typedef struct _memory_private memory_private; typedef struct _memory_private memory_private;
typedef struct _palette_private palette_private; typedef struct _palette_private palette_private;
typedef struct _romload_private romload_private; typedef struct _romload_private romload_private;
typedef struct _input_private input_private;
typedef struct _input_port_private input_port_private; typedef struct _input_port_private input_port_private;
typedef struct _ui_input_private ui_input_private; typedef struct _ui_input_private ui_input_private;
typedef struct _debugcpu_private debugcpu_private; typedef struct _debugcpu_private debugcpu_private;
@ -331,7 +330,7 @@ public:
// getters // getters
const machine_config &config() const { return m_config; } 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; } const game_driver &system() const { return m_system; }
osd_interface &osd() const { return m_osd; } osd_interface &osd() const { return m_osd; }
resource_pool &respool() { return m_respool; } resource_pool &respool() { return m_respool; }
@ -344,8 +343,8 @@ public:
video_manager &video() const { assert(m_video != NULL); return *m_video; } video_manager &video() const { assert(m_video != NULL); return *m_video; }
tilemap_manager &tilemap() const { assert(m_tilemap != NULL); return *m_tilemap; } 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; } debug_view_manager &debug_view() const { assert(m_debug_view != NULL); return *m_debug_view; }
driver_device *driver_data() const { return m_driver_device; } driver_device *driver_data() const { return &downcast<driver_device &>(root_device()); }
template<class _DriverClass> _DriverClass *driver_data() const { return downcast<_DriverClass *>(m_driver_device); } template<class _DriverClass> _DriverClass *driver_data() const { return &downcast<_DriverClass &>(root_device()); }
machine_phase phase() const { return m_current_phase; } machine_phase phase() const { return m_current_phase; }
bool paused() const { return m_paused || (m_current_phase != MACHINE_PHASE_RUNNING); } bool paused() const { return m_paused || (m_current_phase != MACHINE_PHASE_RUNNING); }
bool exit_pending() const { return m_exit_pending; } 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; } bool scheduled_event_pending() const { return m_exit_pending || m_hard_reset_pending; }
// fetch items by name // 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)); } 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 input_port_config *port(const char *tag);
inline const memory_region *region(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 ioport_list m_portlist; // points to a list of input port configurations
// CPU information // CPU information
cpu_device * firstcpu; // first CPU (allows for quick iteration via typenext) cpu_device * firstcpu; // first CPU
// video-related information // video-related information
gfx_element * gfx[MAX_GFX_ELEMENTS];// array of pointers to graphic sets (chars, sprites) 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 const pen_t * pens; // remapped palette pen numbers
colortable_t * colortable; // global colortable for remapping colortable_t * colortable; // global colortable for remapping
pen_t * shadow_table; // table for looking up a shadowed pen 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 // debugger-related information
UINT32 debug_flags; // the current debug flags UINT32 debug_flags; // the current debug flags
@ -431,7 +430,6 @@ public:
memory_private * memory_data; // internal data from memory.c memory_private * memory_data; // internal data from memory.c
palette_private * palette_data; // internal data from palette.c palette_private * palette_data; // internal data from palette.c
romload_private * romload_data; // internal data from romload.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 input_port_private * input_port_data; // internal data from inptport.c
ui_input_private * ui_input_data; // internal data from uiinput.c ui_input_private * ui_input_data; // internal data from uiinput.c
debugcpu_private * debugcpu_data; // internal data from debugcpu.c debugcpu_private * debugcpu_data; // internal data from debugcpu.c
@ -450,6 +448,13 @@ private:
// internal callbacks // internal callbacks
static void logfile_callback(running_machine &machine, const char *buffer); 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 // internal state
const machine_config & m_config; // reference to the constructed machine_config const machine_config & m_config; // reference to the constructed machine_config
const game_driver & m_system; // reference to the definition of the game machine 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 tilemap_manager * m_tilemap; // internal data from tilemap.c
debug_view_manager * m_debug_view; // internal data from debugvw.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 // system state
machine_phase m_current_phase; // current execution phase machine_phase m_current_phase; // current execution phase
bool m_paused; // paused? bool m_paused; // paused?
@ -716,25 +718,26 @@ device_t *driver_device_creator(const machine_config &mconfig, const char *tag,
// INLINE FUNCTIONS // 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) 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) inline const memory_region *running_machine::region(const char *tag)
{ {
// if tag begins with a :, it's absolute // if tag begins with a :, it's absolute
if (tag[0] == ':') if (tag[0] == ':')
{ return m_regionlist.find(tag);
return m_regionlist.find(&tag[1]);
}
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); assert(this != NULL);
/* set static values */ /* 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 */ /* configure the ports */
m_port[0].m_in_func.resolve(m_in_a_cb, *this); 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) if (callback != NULL)
{ {
ttl7474.m_output_cb.type = DEVCB_TYPE_DEVICE; 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; ttl7474.m_output_cb.writeline = callback;
} }
else else
@ -105,7 +105,7 @@ void ttl7474_device::static_set_comp_output_cb(device_t &device, write_line_devi
if (callback != NULL) if (callback != NULL)
{ {
ttl7474.m_comp_output_cb.type = DEVCB_TYPE_DEVICE; 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; ttl7474.m_comp_output_cb.writeline = callback;
} }
else else

View File

@ -65,9 +65,8 @@ void at28c16_device::device_config_complete()
// on this device // 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: protected:
// device-level overrides // device-level overrides
virtual void device_config_complete(); 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_start();
virtual void device_reset(); virtual void device_reset();

View File

@ -101,7 +101,7 @@ static DEVICE_START( centronics )
centronics->strobe = TRUE; centronics->strobe = TRUE;
/* get printer device */ /* get printer device */
centronics->printer = downcast<printer_image_device *>(device->subdevice("printer")); centronics->printer = device->subdevice<printer_image_device>("printer");
/* resolve callbacks */ /* resolve callbacks */
centronics->out_ack_func.resolve(intf->out_ack_func, *device); 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 // 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) if (m_data_bits != 8 && m_data_bits != 16)
{ mame_printf_error("Invalid data width %d specified\n", m_data_bits);
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;
} }

View File

@ -86,7 +86,7 @@ public:
protected: protected:
// device-level overrides // 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_start();
virtual void device_reset(); virtual void device_reset();

View File

@ -94,9 +94,9 @@ void generic_machine_init(running_machine &machine)
// map devices to the interrupt state // map devices to the interrupt state
memset(state->interrupt_device, 0, sizeof(state->interrupt_device)); memset(state->interrupt_device, 0, sizeof(state->interrupt_device));
device_execute_interface *exec = NULL; execute_interface_iterator iter(machine.root_device());
int index = 0; 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(); state->interrupt_device[index++] = &exec->device();
/* register coin save state */ /* register coin save state */
@ -364,23 +364,18 @@ void nvram_load(running_machine &machine)
} }
} }
device_nvram_interface *nvram = NULL; nvram_interface_iterator iter(machine.root_device());
if (machine.devicelist().first(nvram)) 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; nvram->nvram_load(file);
emu_file file(machine.options().nvram_directory(), OPEN_FLAG_READ); file.close();
if (file.open(nvram_filename(nvram->device(),filename)) == FILERR_NONE)
{
nvram->nvram_load(file);
file.close();
}
else
{
nvram->nvram_reset();
}
} }
else
nvram->nvram_reset();
} }
} }
@ -402,18 +397,15 @@ void nvram_save(running_machine &machine)
} }
} }
device_nvram_interface *nvram = NULL; nvram_interface_iterator iter(machine.root_device());
if (machine.devicelist().first(nvram)) 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; nvram->nvram_save(file);
emu_file file(machine.options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); file.close();
if (file.open(nvram_filename(nvram->device(),filename)) == FILERR_NONE)
{
nvram->nvram_save(file);
file.close();
}
} }
} }
} }

View File

@ -125,10 +125,8 @@ void i2cmem_device::device_config_complete()
// on this device // 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: protected:
// device-level overrides // device-level overrides
virtual void device_config_complete(); 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_start();
virtual void device_reset(); 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) if(callback != NULL)
{ {
i8243.m_readhandler_cb.type = DEVCB_TYPE_DEVICE; 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; i8243.m_readhandler_cb.readdevice = callback;
} }
else else
@ -62,7 +63,8 @@ void i8243_device::static_set_write_handler(device_t &device, write8_device_func
if(callback != NULL) if(callback != NULL)
{ {
i8243.m_writehandler_cb.type = DEVCB_TYPE_DEVICE; 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; i8243.m_writehandler_cb.writedevice = callback;
} }
else else

View File

@ -380,6 +380,9 @@ private:
render_texture * m_overtex; // texture for the overlay 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 // 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: protected:
// device-level overrides // device-level overrides
virtual void device_config_complete(); 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_start();
virtual void device_reset(); virtual void device_reset();

View File

@ -121,10 +121,8 @@ TIMER_CALLBACK( msm6242_device::rtc_inc_callback )
// on this device // 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: protected:
// device-level overrides // device-level overrides
virtual void device_config_complete(); 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_start();
virtual void device_reset(); virtual void device_reset();

View File

@ -75,38 +75,32 @@ void ram_device::device_start()
// checks // 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; const char *ramsize_string = NULL;
int is_valid = FALSE; int is_valid = FALSE;
UINT32 specified_ram = 0; UINT32 specified_ram = 0;
bool error = FALSE;
const char *gamename_option = NULL; const char *gamename_option = NULL;
/* verify default ram value */ /* verify default ram value */
if (default_size() == 0) if (default_size() == 0)
{ mame_printf_error("Invalid default RAM option: %s\n", m_default_size);
mame_printf_error("%s: '%s' has an invalid default RAM option: %s\n", driver.source_file, driver.name, m_default_size);
error = TRUE;
}
/* command line options are only parsed for the device named RAM_TAG */ /* command line options are only parsed for the device named RAM_TAG */
if (tag() != NULL && strcmp(tag(), RAM_TAG) == 0) if (tag() != NULL && strcmp(tag(), RAM_TAG) == 0)
{ {
/* verify command line ram option */ /* verify command line ram option */
ramsize_string = options.ram_size(); ramsize_string = mconfig().options().ram_size();
gamename_option = options.system_name(); gamename_option = mconfig().options().system_name();
if ((ramsize_string != NULL) && (ramsize_string[0] != '\0')) if ((ramsize_string != NULL) && (ramsize_string[0] != '\0'))
{ {
specified_ram = parse_string(ramsize_string); specified_ram = parse_string(ramsize_string);
if (specified_ram == 0) if (specified_ram == 0)
{ mame_printf_error("Cannot recognize the RAM option %s\n", ramsize_string);
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, mconfig().gamedrv().name) == 0)
}
if (gamename_option != NULL && *gamename_option != 0 && strcmp(gamename_option, driver.name) == 0)
{ {
/* compare command line option to default value */ /* compare command line option to default value */
if (default_size() == specified_ram) 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); UINT32 option_ram_size = parse_string(p);
if (option_ram_size == 0) if (option_ram_size == 0)
{ mame_printf_error("Invalid RAM option: %s\n", p);
mame_printf_error("%s: '%s' has an invalid RAM option: %s\n", driver.source_file, driver.name, p);
error = TRUE;
}
if (option_ram_size == specified_ram) if (option_ram_size == specified_ram)
is_valid = TRUE; is_valid = TRUE;
@ -163,18 +154,17 @@ bool ram_device::device_validity_check(emu_options &options, const game_driver &
if (!is_valid) if (!is_valid)
{ {
mame_printf_error("%s: '%s' cannot recognize the RAM option %s", driver.source_file, driver.name, ramsize_string); astring output;
mame_printf_error(" (valid options are %s", m_default_size); output.catprintf("Cannot recognize the RAM option %s", ramsize_string);
output.catprintf(" (valid options are %s", m_default_size);
if (m_extra_options != NULL) if (m_extra_options != NULL)
mame_printf_error(",%s).\n", m_extra_options); output.catprintf(",%s).\n", m_extra_options);
else 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: protected:
virtual void device_start(void); 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: private:
// device state // device state
@ -82,4 +82,7 @@ private:
// device type definition // device type definition
extern const device_type RAM; extern const device_type RAM;
// device iterator
typedef device_type_iterator<&device_creator<ram_device>, ram_device> ram_device_iterator;
#endif /* __RAM_H__ */ #endif /* __RAM_H__ */

View File

@ -81,10 +81,8 @@ TIMER_CALLBACK( rtc9701_device::rtc_inc_callback )
// on this device // 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: protected:
// device-level overrides // 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_start();
virtual void device_reset(); 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) if (our_this->disk == NULL)
{ {
// try to locate the CHD from an image subdevice // 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) if (device->subdevice(diskregion) != NULL)
{ {

View File

@ -78,10 +78,8 @@ TIMER_CALLBACK( v3021_device::rtc_inc_callback )
// on this device // 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: protected:
// device-level overrides // 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_start();
virtual void device_reset(); 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 (w->intf->floppy_drive_tags[drive] != NULL)
{ {
if (device->owner() != NULL) { w->drive = device->siblingdevice(w->intf->floppy_drive_tags[drive]);
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]);
} }
} }
@ -2083,14 +2076,7 @@ static DEVICE_RESET( wd1770 )
if(w->intf->floppy_drive_tags[i]!=NULL) { if(w->intf->floppy_drive_tags[i]!=NULL) {
device_t *img = NULL; device_t *img = NULL;
if (device->owner() != NULL) img = device->siblingdevice(w->intf->floppy_drive_tags[i]);
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]);
if (img!=NULL) { if (img!=NULL) {
floppy_drive_set_controller(img,device); floppy_drive_set_controller(img,device);

View File

@ -104,8 +104,21 @@ static bool print_verbose = false;
static running_machine *global_machine; static running_machine *global_machine;
/* output channels */ /* output channels */
static output_callback_func output_cb[OUTPUT_CHANNEL_COUNT]; static output_delegate output_cb[OUTPUT_CHANNEL_COUNT] =
static void *output_cb_param[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 CORE IMPLEMENTATION
@ -151,7 +164,10 @@ int mame_execute(emu_options &options, osd_interface &osd)
// otherwise, perform validity checks before anything else // otherwise, perform validity checks before anything else
else else
validate_drivers(options, system); {
validity_checker valid(options);
valid.check_shared_source(*system);
}
firstgame = false; firstgame = false;
@ -203,20 +219,17 @@ int mame_execute(emu_options &options, osd_interface &osd)
channel 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(channel < OUTPUT_CHANNEL_COUNT);
assert(callback != NULL); assert(!callback.isnull());
/* return the originals if requested */ /* return the originals if requested */
if (prevcb != NULL) output_delegate prevcb = output_cb[channel];
*prevcb = output_cb[channel];
if (prevparam != NULL)
*prevparam = output_cb_param[channel];
/* set the new ones */ /* set the new ones */
output_cb[channel] = callback; 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 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 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; 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 */ /* do the output */
va_start(argptr, format); 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); va_end(argptr);
} }
@ -273,16 +279,9 @@ void mame_printf_warning(const char *format, ...)
{ {
va_list argptr; 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 */ /* do the output */
va_start(argptr, format); 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); va_end(argptr);
} }
@ -296,16 +295,9 @@ void mame_printf_info(const char *format, ...)
{ {
va_list argptr; 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 */ /* do the output */
va_start(argptr, format); 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); va_end(argptr);
} }
@ -323,16 +315,9 @@ void mame_printf_verbose(const char *format, ...)
if (!print_verbose) if (!print_verbose)
return; 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 */ /* do the output */
va_start(argptr, format); 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); va_end(argptr);
} }
@ -346,21 +331,9 @@ void mame_printf_debug(const char *format, ...)
{ {
va_list argptr; 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 */ /* do the output */
va_start(argptr, format); 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); va_end(argptr);
} }
@ -375,16 +348,9 @@ void mame_printf_log(const char *format, ...)
{ {
va_list argptr; 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 */ /* do the output */
va_start(argptr, format); 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); va_end(argptr);
} }
#endif #endif

View File

@ -49,7 +49,7 @@ enum
//************************************************************************** //**************************************************************************
// output channel callback // 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 class emulator_info
{ {
@ -76,6 +76,8 @@ public:
static void printf_usage(const char *par1, const char *par2); static void printf_usage(const char *par1, const char *par2);
}; };
//************************************************************************** //**************************************************************************
// GLOBAL VARIABLES // GLOBAL VARIABLES
//************************************************************************** //**************************************************************************
@ -102,11 +104,11 @@ int mame_is_valid_machine(running_machine &machine);
/* ----- output management ----- */ /* ----- output management ----- */
/* set the output handler for a channel, returns the current one */ /* 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 */ /* built-in default callbacks */
void mame_file_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(void *param, 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 */ /* calls to be used by the code */
void mame_printf_error(const char *format, ...) ATTR_PRINTF(1,2); 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_total_colors(0),
m_default_layout(NULL), m_default_layout(NULL),
m_gamedrv(gamedrv), m_gamedrv(gamedrv),
m_options(options) m_options(options),
m_root_device(NULL)
{ {
// construct the config // construct the config
(*gamedrv.machine_config)(*this, NULL); (*gamedrv.machine_config)(*this, NULL);
// intialize slot devices - make sure that any required devices have been allocated // intialize slot devices - make sure that any required devices have been allocated
device_slot_interface *slot = NULL; slot_interface_iterator slotiter(root_device());
for (bool gotone = m_devicelist.first(slot); gotone; gotone = slot->next(slot)) for (device_slot_interface *slot = slotiter.first(); slot != NULL; slot = slotiter.next())
{ {
const slot_interface *intf = slot->get_slot_interfaces(); const slot_interface *intf = slot->get_slot_interfaces();
if (intf != NULL) if (intf != NULL)
@ -77,16 +78,19 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options)
device_t &owner = slot->device(); device_t &owner = slot->device();
const char *selval = options.value(owner.tag()); const char *selval = options.value(owner.tag());
if (!options.exists(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; bool found = false;
for (int i = 0; intf[i].name != NULL; i++) { for (int i = 0; intf[i].name != NULL; i++)
if (strcmp(selval, intf[i].name) == 0) { {
if (strcmp(selval, intf[i].name) == 0)
{
device_t *new_dev = device_add(&owner, intf[i].name, intf[i].devtype, 0); device_t *new_dev = device_add(&owner, intf[i].name, intf[i].devtype, 0);
found = true; found = true;
const char *def = slot->get_default_card(devicelist(), options); const char *def = slot->get_default_card(*this, options);
if ((def!=NULL) && (strcmp(def,selval)==0)) if (def != NULL && strcmp(def, selval) == 0)
device_t::static_set_input_default(*new_dev, slot->input_ports_defaults()); 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 // when finished, set the game driver
device_t *root = m_devicelist.find("root"); driver_device::static_set_game(*m_root_device, gamedrv);
if (root == NULL)
throw emu_fatalerror("Machine configuration missing driver_device");
driver_device::static_set_game(*root, gamedrv);
// then notify all devices that their configuration is complete // 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()) if (!device->configured())
device->config_complete(); device->config_complete();
} }
@ -115,6 +117,7 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options)
machine_config::~machine_config() machine_config::~machine_config()
{ {
global_free(m_root_device);
} }
@ -125,46 +128,8 @@ machine_config::~machine_config()
screen_device *machine_config::first_screen() const screen_device *machine_config::first_screen() const
{ {
return downcast<screen_device *>(m_devicelist.first(SCREEN)); screen_device_iterator iter(root_device());
} return iter.first();
//-------------------------------------------------
// 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;
}
}
} }
@ -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) device_t *machine_config::device_add(device_t *owner, const char *tag, device_type type, UINT32 clock)
{ {
astring tempstring; // if there's an owner, let the owner do the work
const char *fulltag = owner->subtag(tempstring, tag); if (owner != NULL)
device_t *device = &m_devicelist.append(fulltag, *(*type)(*this, fulltag, owner, clock)); return owner->add_subdevice(type, tag, clock);
device_add_subdevices(device);
return device; // 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) device_t *machine_config::device_replace(device_t *owner, const char *tag, device_type type, UINT32 clock)
{ {
astring tempstring; // find the original device by this name (must exist)
const char *fulltag = owner->subtag(tempstring, tag); assert(owner != NULL);
device_remove_subdevices(m_devicelist.find(fulltag)); device_t *device = owner->subdevice(tag);
device_t *device = &m_devicelist.replace_and_remove(fulltag, *(*type)(*this, fulltag, owner, clock)); if (device == NULL)
device_add_subdevices(device); {
return device; 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) device_t *machine_config::device_remove(device_t *owner, const char *tag)
{ {
astring tempstring; // find the original device by this name (must exist)
const char *fulltag = owner->subtag(tempstring, tag); assert(owner != NULL);
device_t *device=m_devicelist.find(fulltag); device_t *device = owner->subdevice(tag);
device_remove_subdevices(device); if (device == NULL)
m_devicelist.remove(*device); {
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; 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) device_t *machine_config::device_find(device_t *owner, const char *tag)
{ {
astring tempstring; // find the original device by this name (must exist)
const char *fulltag = owner->subtag(tempstring, tag); assert(owner != NULL);
device_t *device = m_devicelist.find(fulltag); device_t *device = owner->subdevice(tag);
assert(device != NULL);
if (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; return device;
} }

View File

@ -131,10 +131,11 @@ public:
// getters // getters
const game_driver &gamedrv() const { return m_gamedrv; } const game_driver &gamedrv() const { return m_gamedrv; }
const device_list &devicelist() const { return m_devicelist; } device_t &root_device() const { assert(m_root_device != NULL); return *m_root_device; }
const device_t *first_device() const { return m_devicelist.first(); }
screen_device *first_screen() const; screen_device *first_screen() const;
emu_options &options() const { return m_options; } 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 // public state
attotime m_minimum_quantum; // minimum scheduling quantum 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 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 attotime m_watchdog_time; // length of time until the watchdog kills us
// legacy callbacks
nvram_handler_func m_nvram_handler; // NVRAM save/load callback nvram_handler_func m_nvram_handler; // NVRAM save/load callback
memcard_handler_func m_memcard_handler; // memory card 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 UINT32 m_video_attributes; // flags describing the video system
const gfx_decode_entry *m_gfxdecodeinfo; // pointer to array of graphics decoding information const gfx_decode_entry *m_gfxdecodeinfo; // pointer to array of graphics decoding information
UINT32 m_total_colors; // total number of colors in the palette 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); device_t *device_find(device_t *owner, const char *tag);
private: private:
void device_add_subdevices(device_t *device); // internal state
void device_remove_subdevices(const device_t *device);
const game_driver & m_gamedrv; const game_driver & m_gamedrv;
emu_options & m_options; 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; memdata->banknext = STATIC_BANK1;
// loop over devices and spaces within each device // loop over devices and spaces within each device
device_memory_interface *memory = NULL; memory_interface_iterator iter(machine.root_device());
for (bool gotone = machine.devicelist().first(memory); gotone; gotone = memory->next(memory)) for (device_memory_interface *memory = iter.first(); memory != NULL; memory = iter.next())
for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++) for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++)
{ {
// if there is a configuration for this space, we need an address space // 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) 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 // 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) 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) if (base == NULL)
fatalerror("memory_configure_bank called NULL base"); 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 // memory_configure_bank_decrypted - configure
// addresses for a bank // 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_decrypted(machine.root_device(), tag, startentry, numentries, base, stride);
memory_configure_bank(device->machine(), device->subtag(tempstring, 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 // 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 // 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) 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) if (base == NULL)
fatalerror("memory_configure_bank_decrypted called NULL base"); 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 // memory_set_bank - select one pre-configured
// entry to be the new bank base // 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) void memory_set_bank(running_machine &machine, const char *tag, int entrynum)
{ {
// validation checks memory_set_bank(machine.root_device(), tag, entrynum);
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);
} }
@ -1860,10 +1854,16 @@ void memory_set_bank(running_machine &machine, const char *tag, int entrynum)
// entry to be the new bank base // 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; // validation checks
memory_set_bank(device->machine(), device->subtag(tempstring, tag), entrynum); 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) int memory_get_bank(running_machine &machine, const char *tag)
{ {
// validation checks return memory_get_bank(machine.root_device(), tag);
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();
} }
@ -1889,10 +1883,16 @@ int memory_get_bank(running_machine &machine, const char *tag)
// selected bank // selected bank
//------------------------------------------------- //-------------------------------------------------
int memory_get_bank(device_t *device, const char *tag) int memory_get_bank(device_t &device, const char *tag)
{ {
astring tempstring; // validation checks
return memory_get_bank(device->machine(), device->subtag(tempstring, tag)); astring fulltag;
memory_bank *bank = device.machine().memory_data->bankmap.find_hash_only(device.subtag(fulltag, tag));
if (bank == NULL)
fatalerror("memory_get_bank called for unknown bank '%s'", 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) void memory_set_bankptr(running_machine &machine, const char *tag, void *base)
{ {
// validation checks memory_set_bankptr(machine.root_device(), tag, base);
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);
} }
@ -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 // 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; // validation checks
return memory_set_bankptr(device->machine(), device->subtag(tempstring, tag), base); 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) 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) if (share == NULL)
return NULL; return NULL;
length = share->size(); 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); 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 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)); // if we can't find it, add it to our map
memory_share *share = auto_alloc(machine(), memory_share(entry->m_byteend + 1 - entry->m_bytestart)); astring fulltag;
machine().memory_data->sharemap.add(entry->m_share, share, false); 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 // 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 // validate adjusted addresses against implicit regions
if (entry->m_region != NULL && entry->m_share == NULL && entry->m_baseptr == NULL) 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 // find the region
if (entry->m_region[0] == ':') const memory_region *region = machine().region(fulltag);
{
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());
if (region == NULL) 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); 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 // convert any region-relative entries to their memory pointers
if (entry->m_region != NULL) { if (entry->m_region != NULL)
astring regiontag; {
if (strchr(entry->m_region,':')) { // determine full tag
regiontag = entry->m_region; astring fulltag;
} else { device().siblingtag(fulltag, entry->m_region);
m_device.siblingtag(regiontag, entry->m_region);
} // set the memory address
entry->m_memory = machine().region(regiontag.cstr())->base() + entry->m_rgnoffs; 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) 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; 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 // based on the handler type, alter the bits, name, funcptr, and object
switch (data.m_type) switch (data.m_type)
@ -2313,25 +2310,25 @@ void address_space::populate_map_entry(const address_map_entry &entry, read_or_w
break; break;
case AMH_DEVICE_DELEGATE: case AMH_DEVICE_DELEGATE:
device = machine().device(data.m_tag); target_device = device().siblingdevice(data.m_tag);
if (device == NULL) 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, m_name, m_device.tag()); 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) if (readorwrite == ROW_READ)
switch (data.m_bits) 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 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, *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, *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, *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 else
switch (data.m_bits) 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 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, *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, *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, *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; break;
@ -2355,42 +2352,42 @@ void address_space::populate_map_entry(const address_map_entry &entry, read_or_w
break; break;
case AMH_LEGACY_DEVICE_HANDLER: case AMH_LEGACY_DEVICE_HANDLER:
device = machine().device(data.m_tag); target_device = device().siblingdevice(data.m_tag);
if (device == NULL) if (target_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()); 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) if (readorwrite == ROW_READ)
switch (data.m_bits) 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 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(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice16, 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(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice32, 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(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice64, 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 else
switch (data.m_bits) 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 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(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice16, 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(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice32, 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(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice64, 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; break;
case AMH_PORT: case AMH_PORT:
install_readwrite_port(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, install_readwrite_port(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror,
(readorwrite == ROW_READ) ? data.m_tag : NULL, (readorwrite == ROW_READ) ? data.m_tag.cstr() : NULL,
(readorwrite == ROW_WRITE) ? data.m_tag : NULL); (readorwrite == ROW_WRITE) ? data.m_tag.cstr() : NULL);
break; break;
case AMH_BANK: case AMH_BANK:
install_bank_generic(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, install_bank_generic(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror,
(readorwrite == ROW_READ) ? data.m_tag : NULL, (readorwrite == ROW_READ) ? data.m_tag.cstr() : NULL,
(readorwrite == ROW_WRITE) ? data.m_tag : NULL); (readorwrite == ROW_WRITE) ? data.m_tag.cstr() : NULL);
break; break;
case AMH_DEVICE_SUBMAP: 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) if (entry->m_baseptr != NULL)
*entry->m_baseptr = entry->m_memory; *entry->m_baseptr = entry->m_memory;
if (entry->m_baseptroffs_plus1 != 0) 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) if (entry->m_genbaseptroffs_plus1 != 0)
*(void **)((UINT8 *)&machine().generic + entry->m_genbaseptroffs_plus1 - 1) = entry->m_memory; *(void **)((UINT8 *)&machine().generic + entry->m_genbaseptroffs_plus1 - 1) = entry->m_memory;
if (entry->m_sizeptr != NULL) if (entry->m_sizeptr != NULL)
*entry->m_sizeptr = entry->m_byteend - entry->m_bytestart + 1; *entry->m_sizeptr = entry->m_byteend - entry->m_bytestart + 1;
if (entry->m_sizeptroffs_plus1 != 0) 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) if (entry->m_gensizeptroffs_plus1 != 0)
*(size_t *)((UINT8 *)&machine().generic + entry->m_gensizeptroffs_plus1 - 1) = entry->m_byteend - entry->m_bytestart + 1; *(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 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) 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) if (share != NULL && share->ptr() != NULL)
{ {
entry->m_memory = share->ptr(); 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 we're the first match on a shared pointer, assign it now
if (entry->m_memory != NULL && entry->m_share != NULL) 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) if (share != NULL && share->ptr() == NULL)
{ {
share->set_ptr(entry->m_memory); 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) if (rtag != NULL)
{ {
// find the port // 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) 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()); 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) if (wtag != NULL)
{ {
// find the port // 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) 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()); 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 // map the read bank
if (rtag != NULL) 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()); read().map_range(addrstart, addrend, addrmask, addrmirror, bank.index());
} }
// map the write bank // map the write bank
if (wtag != NULL) 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()); 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 we are sharing, and we don't have a pointer yet, create one
if (entry->m_share != NULL) 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) if (share != NULL && share->ptr() == NULL)
return true; return true;
} }

View File

@ -676,23 +676,23 @@ void memory_init(running_machine &machine);
// configure the addresses for a bank // 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(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 // 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(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 // 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(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 // return the currently selected bank
int memory_get_bank(running_machine &machine, const char *tag); 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 // 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(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 // get a pointer to a shared memory region by tag
void *memory_get_shared(running_machine &machine, const char *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) static void network_load(running_machine &machine, int config_type, xml_data_node *parentnode)
{ {
xml_data_node *node; xml_data_node *node;
device_network_interface *network = NULL;
if ((config_type == CONFIG_TYPE_GAME) && (parentnode != 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")) 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')) 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())) { if (!strcmp(tag, network->device().tag())) {
int interface = xml_get_attribute_int(node, "interface", 0); 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) static void network_save(running_machine &machine, int config_type, xml_data_node *parentnode)
{ {
xml_data_node *node; xml_data_node *node;
device_network_interface *network = NULL;
/* only care about game-specific data */ /* only care about game-specific data */
if (config_type == CONFIG_TYPE_GAME) 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); node = xml_add_child(parentnode, "device", NULL);
if (node != 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 // loop over all types and generate the string
device_iterator iter(machine.root_device());
for (curtype = PROFILER_DEVICE_FIRST; curtype < PROFILER_TOTAL; curtype++) for (curtype = PROFILER_DEVICE_FIRST; curtype < PROFILER_TOTAL; curtype++)
{ {
// determine the accumulated time for this type // 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 // and then the text
if (curtype >= PROFILER_DEVICE_FIRST && curtype <= PROFILER_DEVICE_MAX) 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 else
for (int nameindex = 0; nameindex < ARRAY_LENGTH(names); nameindex++) for (int nameindex = 0; nameindex < ARRAY_LENGTH(names); nameindex++)
if (names[nameindex].type == curtype) 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 // 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 (view == NULL && scrcount > 0)
{ {
// if we have enough targets to be one per screen, assign in order // if we have enough targets to be one per screen, assign in order
if (numtargets >= scrcount) if (numtargets >= scrcount)
{ {
int ourindex = index() % scrcount; int ourindex = index() % scrcount;
screen_device *screen; screen_device *screen = iter.byindex(ourindex);
for (screen = m_manager.machine().first_screen(); screen != NULL; screen = screen->next_screen())
if (ourindex-- == 0)
break;
// find the first view with this screen and this screen only // 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)) 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) if (viewscreens.count() >= scrcount)
{ {
screen_device *screen; 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)) if (!viewscreens.contains(*screen))
break; break;
if (screen == NULL) if (screen == NULL)
@ -1576,7 +1574,8 @@ void render_target::load_layout_files(const char *layoutfile, bool singlefile)
else else
have_default |= true; 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 // now do the built-in layouts for single-screen games
if (screens == 1) 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)); 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 // 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)); 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]; char temp[100];
// screen 0 parameters // 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 // native X aspect factor
sprintf(temp, "~scr%dnativexaspect~", scrnum); sprintf(temp, "~scr%dnativexaspect~", scrnum);
if (!strncmp(string, temp, strlen(temp))) 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 // fetch common data
int index = xml_get_attribute_int_with_subst(machine, itemnode, "index", -1); int index = xml_get_attribute_int_with_subst(machine, itemnode, "index", -1);
if (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); m_input_mask = xml_get_attribute_int_with_subst(machine, itemnode, "inputmask", 0);
if (m_output_name[0] != 0 && m_element != NULL) if (m_output_name[0] != 0 && m_element != NULL)
output_set_value(m_output_name, m_element->default_state()); 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) const rom_source *rom_first_source(const machine_config &config)
{ {
/* look through devices */ /* 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) if (device->rom_region() != NULL)
return device; 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) const rom_source *rom_next_source(const rom_source &previous)
{ {
/* look for further devices with ROM definitions */ /* 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) if (device->rom_region() != NULL)
return (rom_source *)device; return device;
return NULL; 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) 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; device_execute_interface **suspend_tailptr = &suspend_list;
// iterate over all devices // iterate over all devices
device_execute_interface *exec = NULL; execute_interface_iterator iter(machine().root_device());
for (bool gotone = machine().devicelist().first(exec); gotone; gotone = exec->next(exec)) for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
{ {
// append to the appropriate list // append to the appropriate list
exec->m_nextexec = NULL; exec->m_nextexec = NULL;

View File

@ -244,42 +244,26 @@ void screen_device::static_set_screen_vblank(device_t &device, screen_vblank_del
// configuration // 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 // sanity check dimensions
if (m_width <= 0 || m_height <= 0) if (m_width <= 0 || m_height <= 0)
{ mame_printf_error("Invalid display dimensions\n");
mame_printf_error("%s: %s screen '%s' has invalid display dimensions\n", driver.source_file, driver.name, tag());
error = true;
}
// sanity check display area // sanity check display area
if (m_type != SCREEN_TYPE_VECTOR) if (m_type != SCREEN_TYPE_VECTOR)
{ {
if (m_visarea.empty() || m_visarea.max_x >= m_width || m_visarea.max_y >= m_height) if (m_visarea.empty() || m_visarea.max_x >= m_width || m_visarea.max_y >= m_height)
{ mame_printf_error("Invalid display area\n");
mame_printf_error("%s: %s screen '%s' has an invalid display area\n", driver.source_file, driver.name, tag());
error = true;
}
// sanity check screen formats // sanity check screen formats
if (m_screen_update_ind16.isnull() && m_screen_update_rgb32.isnull()) if (m_screen_update_ind16.isnull() && m_screen_update_rgb32.isnull())
{ mame_printf_error("Missing SCREEN_UPDATE function\n");
mame_printf_error("%s: %s screen '%s' has no SCREEN_UPDATE function\n", driver.source_file, driver.name, tag());
error = true;
}
} }
// check for zero frame rate // check for zero frame rate
if (m_refresh == 0) if (m_refresh == 0)
{ mame_printf_error("Invalid (zero) refresh rate\n");
mame_printf_error("%s: %s screen '%s' has a zero refresh rate\n", driver.source_file, driver.name, tag());
error = true;
}
return error;
} }

View File

@ -192,7 +192,6 @@ public:
static void static_set_screen_vblank(device_t &device, screen_vblank_delegate callback); static void static_set_screen_vblank(device_t &device, screen_vblank_delegate callback);
// information getters // information getters
screen_device *next_screen() const { return downcast<screen_device *>(typenext()); }
render_container &container() const { assert(m_container != NULL); return *m_container; } render_container &container() const { assert(m_container != NULL); return *m_container; }
// dynamic configuration // dynamic configuration
@ -244,7 +243,7 @@ private:
}; };
// device-level overrides // 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_start();
virtual void device_stop(); virtual void device_stop();
virtual void device_post_load(); virtual void device_post_load();
@ -334,6 +333,9 @@ private:
// device type definition // device type definition
extern const device_type SCREEN; 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; 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 EXPAT INTERFACES
***************************************************************************/ ***************************************************************************/
@ -1216,7 +1273,7 @@ static int softlist_penalty_compare(const char *source, const char *target)
software_list_find_approx_matches 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 #undef rand
@ -1243,7 +1300,7 @@ void software_list_find_approx_matches(software_list_config *swlistcfg, software
software_info *candidate = swinfo; software_info *candidate = swinfo;
software_part *part = software_find_part(swinfo, NULL, NULL); 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 */ /* pick the best match between driver name and description */
@ -1442,19 +1499,19 @@ software_part *software_part_next(software_part *part)
software_display_matches 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 // 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" mame_printf_error("\n\"%s\" approximately matches the following\n"
"supported software items (best match first):\n\n", name); "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) if (list)
{ {
@ -1467,10 +1524,10 @@ void software_display_matches(const device_list &devlist,emu_options &options, c
if (matches[0] != 0) if (matches[0] != 0)
{ {
if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) 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)); mame_printf_error("* Software list \"%s\" (%s) matches: \n", swlist->list_name(), software_list_get_description(list));
else 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 // print them out
for (softnum = 0; softnum < ARRAY_LENGTH(matches); softnum++) 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; char *swlist_name, *swname, *swpart; //, *swname_bckp;
*software_list_ptr = NULL; *software_list_ptr = NULL;
@ -1516,33 +1573,28 @@ static void find_software_item(const device_list &devlist, emu_options &options,
else else
{ {
/* Loop through all the software lists named in the driver */ /* 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)
{ {
if ( *software_list_ptr )
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 ) 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_part_ptr = software_find_part( *software_info_ptr, swpart, interface );
} if (*software_part_ptr) break;
*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;
}
} }
} }
} }
@ -1634,12 +1686,12 @@ bool load_software_part(emu_options &options, device_image_interface *image, con
*sw_info = NULL; *sw_info = NULL;
*sw_part = 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 no match has been found, we suggest similar shortnames
if (software_info_ptr == NULL) 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 ) 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 ); *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 ); 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)) { 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; break;
} }
@ -1723,12 +1775,12 @@ bool load_software_part(emu_options &options, device_image_interface *image, con
software_part *req_software_part_ptr = NULL; software_part *req_software_part_ptr = NULL;
const char *req_swlist_name = 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 ) if ( req_software_list_ptr )
{ {
device_image_interface *req_image = NULL; image_interface_iterator imgiter(image->device().machine().root_device());
for (bool gotone = image->device().machine().devicelist().first(req_image); gotone; gotone = req_image->next(req_image)) for (device_image_interface *req_image = imgiter.first(); req_image != NULL; req_image = imgiter.next())
{ {
const char *interface = req_image->image_interface(); const char *interface = req_image->image_interface();
if (interface != NULL) if (interface != NULL)
@ -1791,7 +1843,7 @@ const char *software_part_get_feature(const software_part *part, const char *fea
software_get_default_slot 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* retVal = NULL;
const char* path = options.value(image->instance_name()); 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) { if (strlen(path)>0) {
retVal = default_card_slot; 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) { if (software_part_ptr!=NULL) {
const char *slot = software_part_get_feature(software_part_ptr, "slot"); const char *slot = software_part_get_feature(software_part_ptr, "slot");
if (slot!=NULL) { if (slot!=NULL) {
@ -1819,10 +1871,10 @@ const char *software_part_get_feature(const software_part *part, const char *fea
is_software_compatible 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 *compatibility = software_part_get_feature(swpart, "compatibility");
const char *filter = swlist->filter; const char *filter = swlist->filter();
if ((compatibility==NULL) || (filter==NULL)) return TRUE; if ((compatibility==NULL) || (filter==NULL)) return TRUE;
astring comp = astring(compatibility,","); astring comp = astring(compatibility,",");
char *filt = core_strdup(filter); 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) 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); // add to the global map whenever we check a list so we don't re-check
// first determine the maximum number of lists we might encounter // it in the future
int list_count = 0; if (s_checked_lists.add(m_list_name, 1, false) == TMERR_DUPLICATE)
while (drivlist.next()) return;
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) softlist_map names;
list_count++; softlist_map descriptions;
}
// allocate a list enum { NAME_LEN_PARENT = 8, NAME_LEN_CLONE = 16 };
astring *lists = global_alloc_array(astring, list_count);
bool error = FALSE; software_list *list = software_list_open(mconfig().options(), m_list_name, FALSE, NULL);
if (list_count) if ( list )
{ {
drivlist.reset(); software_list_parse( list, &validate_error_proc, NULL );
list_count = 0;
while (drivlist.next()) for (software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo))
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(); const char *s;
softlist_map names; int is_clone = 0;
softlist_map descriptions;
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); /* Did we lost any description? */
if ( list ) if (swinfo->longname == NULL)
{ {
/* Verify if we have encountered this list before */ mame_printf_error("%s: %s has no description\n", list->file->filename(), swinfo->shortname);
bool seen_before = false; break;
for (int seen_index = 0; seen_index < list_count && !seen_before; seen_index++) }
if (lists[seen_index] == swlist->list_name)
seen_before = true;
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; mame_printf_error("%s: %s is set as a clone of itself\n", list->file->filename(), swinfo->shortname);
software_list_parse( list, &validate_error_proc, NULL ); 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; const char *str;
int is_clone = 0;
/* First, check if the xml got corrupted: */ /* make sure it's all lowercase */
for (str = data->_name; *str; str++)
/* Did we lost any description? */ if (tolower((UINT8)*str) != *str)
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)
{ {
mame_printf_error("%s: %s is set as a clone of itself\n", list->file->filename(), swinfo->shortname); mame_printf_error("%s: %s has upper case ROM name %s\n", list->file->filename(), swinfo->shortname, data->_name);
error = TRUE;
break; break;
} }
/* make sure the parent exists */ /* make sure the hash is valid */
software_info *swinfo2 = software_list_find(list, swinfo->parentname, NULL ); hash_collection hashes;
if (!hashes.from_internal_string(data->_hashdata))
if (!swinfo2) mame_printf_error("%s: %s has rom '%s' with an invalid hash string '%s'\n", list->file->filename(), swinfo->shortname, data->_name, data->_hashdata);
{
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;
}
}
}
}
} }
} }
software_list_close(list);
} }
} }
} software_list_close(list);
if (error)
throw emu_fatalerror(MAMERR_FAILED_VALIDITY, "Validity checks failed");
}
DEVICE_GET_INFO( software_list )
{
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_TOKEN_BYTES: info->i = 1; break;
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(software_list_config); break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( software_list ); break;
case DEVINFO_FCT_STOP: /* Nothing */ break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: strcpy(info->s, "Software lists"); break;
case DEVINFO_STR_FAMILY: strcpy(info->s, "Software lists"); break;
case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright MESS Team"); break;
} }
} }
DEFINE_LEGACY_DEVICE(SOFTWARE_LIST, software_list);

View File

@ -14,6 +14,84 @@
#include "pool.h" #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 Internal structures and XML file handling
@ -95,13 +173,6 @@ struct software_list
int list_entries; int list_entries;
}; };
struct software_list_config
{
char *list_name;
UINT32 list_type;
const char *filter;
};
/* Handling a software list */ /* Handling a software list */
software_list *software_list_open(emu_options &options, const char *listname, int is_preload, void (*error_proc)(const char *message)); 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); 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); 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_device *swlist);
bool is_software_compatible(const software_part *swpart, const software_list_config *swlist);
bool swinfo_has_multiple_parts(const software_info *swinfo, const char *interface); 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 #endif

View File

@ -788,7 +788,10 @@ sound_manager::sound_manager(running_machine &machine)
machine.m_sample_rate = 11025; machine.m_sample_rate = 11025;
// count the speakers // 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 // allocate memory for mix buffers
m_leftmix = auto_alloc_array(machine, INT32, machine.sample_rate()); 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 bool sound_manager::indexed_speaker_input(int index, speaker_input &info) const
{ {
// scan through the speakers until we find the indexed input // 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()) if (index < info.speaker->inputs())
{ {
@ -899,8 +903,8 @@ void sound_manager::mute(bool mute, UINT8 reason)
void sound_manager::reset() void sound_manager::reset()
{ {
// reset all the sound chips // reset all the sound chips
device_sound_interface *sound = NULL; sound_interface_iterator iter(machine().root_device());
for (bool gotone = machine().devicelist().first(sound); gotone; gotone = sound->next(sound)) for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next())
sound->device().reset(); sound->device().reset();
} }
@ -1003,7 +1007,8 @@ void sound_manager::update()
// force all the speaker streams to generate the proper number of samples // force all the speaker streams to generate the proper number of samples
int samples_this_update = 0; 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)); speaker->mix(m_leftmix, m_rightmix, samples_this_update, (m_muted & MUTE_REASON_SYSTEM));
// now downmix the final result // 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() void bsmt2000_device::device_start()
{ {
// find our CPU // find our CPU
m_cpu = downcast<tms32015_device*>(subdevice("bsmt2000")); m_cpu = subdevice<tms32015_device>("bsmt2000");
// find our direct access // find our direct access
m_direct = &space()->direct(); 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_t *cdda_from_cdrom(running_machine &machine, void *file)
{ {
device_sound_interface *sound = NULL; sound_interface_iterator iter(machine.root_device());
for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next())
for (bool gotone = machine.devicelist().first(sound); gotone; gotone = sound->next(sound))
if (sound->device().type() == CDDA) if (sound->device().type() == CDDA)
{ {
cdda_info *info = get_safe_token(*sound); cdda_info *info = get_safe_token(*sound);

View File

@ -75,7 +75,8 @@ DISCRETE_RESET(dss_adjustment)
{ {
double min, max; 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) if (m_port == NULL)
fatalerror("DISCRETE_ADJUSTMENT - NODE_%d has invalid tag", this->index()); 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); DECLARE_LEGACY_SOUND_DEVICE(SAMPLES, samples);
typedef device_type_iterator<&legacy_device_creator<samples_device>, samples_device> samples_device_iterator;
#endif /* __SAMPLES_H__ */ #endif /* __SAMPLES_H__ */

View File

@ -22,7 +22,6 @@
static STREAM_UPDATE( wave_sound_update ) static STREAM_UPDATE( wave_sound_update )
{ {
cassette_image_device *cass = (cassette_image_device *)param; cassette_image_device *cass = (cassette_image_device *)param;
int speakers = cass->machine().devicelist().count(SPEAKER);
cassette_image *cassette; cassette_image *cassette;
cassette_state state; cassette_state state;
double time_index; double time_index;
@ -31,6 +30,8 @@ static STREAM_UPDATE( wave_sound_update )
stream_sample_t *right_buffer = NULL; stream_sample_t *right_buffer = NULL;
int i; int i;
speaker_device_iterator spkiter(cass->machine().root_device());
int speakers = spkiter.count();
if (speakers>1) if (speakers>1)
right_buffer = outputs[1]; right_buffer = outputs[1];
@ -71,7 +72,8 @@ static DEVICE_START( wave )
assert( device != NULL ); assert( device != NULL );
assert( device->static_config() != 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())); image = dynamic_cast<cassette_image_device *>(device->machine().device( (const char *)device->static_config()));
if (speakers > 1) if (speakers > 1)
device->machine().sound().stream_alloc(*device, 0, 2, device->machine().sample_rate(), (void *)image, wave_sound_update); 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 // inline configuration helpers
static void static_set_position(device_t &device, double x, double y, double z); 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 // internally for use by the sound system
void mix(INT32 *leftmix, INT32 *rightmix, int &samples_this_update, bool suppress); void mix(INT32 *leftmix, INT32 *rightmix, int &samples_this_update, bool suppress);
@ -117,4 +114,8 @@ protected:
extern const device_type SPEAKER; extern const device_type SPEAKER;
// speaker device iterator
typedef device_type_iterator<&device_creator<speaker_device>, speaker_device> speaker_device_iterator;
#endif /* __SOUND_H__ */ #endif /* __SOUND_H__ */

View File

@ -176,54 +176,40 @@ void timer_device::static_set_ptr(device_t &device, void *ptr)
// configuration // 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 // type based configuration
switch (m_type) switch (m_type)
{ {
case TIMER_TYPE_GENERIC: case TIMER_TYPE_GENERIC:
if (m_screen_tag != NULL || m_first_vpos != 0 || m_start_delay != attotime::zero) 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) 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; break;
case TIMER_TYPE_PERIODIC: case TIMER_TYPE_PERIODIC:
if (m_screen_tag != NULL || m_first_vpos != 0) 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) if (m_period <= attotime::zero)
{ mame_printf_error("Periodic timer specified invalid period\n");
mame_printf_error("%s: %s periodic timer '%s' specified invalid period\n", driver.source_file, driver.name, tag());
error = true;
}
break; break;
case TIMER_TYPE_SCANLINE: case TIMER_TYPE_SCANLINE:
if (m_period != attotime::zero || m_start_delay != attotime::zero) 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) 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) if (m_first_vpos < 0)
{ mame_printf_error("Scanline timer specified invalid initial position\n");
mame_printf_error("%s: %s scanline timer '%s' specified invalid initial position\n", driver.source_file, driver.name, tag());
error = true;
}
if (m_increment < 0) if (m_increment < 0)
{ mame_printf_error("Scanline timer specified invalid increment\n");
mame_printf_error("%s: %s scanline timer '%s' specified invalid increment\n", driver.source_file, driver.name, tag());
error = true;
}
break; break;
default: default:
mame_printf_error("%s: %s timer '%s' has an invalid type\n", driver.source_file, driver.name, tag()); mame_printf_error("Invalid type specified\n");
error = true;
break; break;
} }
return error;
} }

View File

@ -142,7 +142,7 @@ public:
private: private:
// device-level overrides // 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_start();
virtual void device_reset(); virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); 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) 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; int found_sound = FALSE;
/* print description, manufacturer, and CPU: */ /* print description, manufacturer, and CPU: */
string.printf("%s\n%s %s\n\nCPU:\n", machine.system().description, machine.system().year, machine.system().manufacturer); string.printf("%s\n%s %s\n\nCPU:\n", machine.system().description, machine.system().year, machine.system().manufacturer);
/* loop over all CPUs */ /* loop over all CPUs */
device_execute_interface *exec = NULL; execute_interface_iterator execiter(machine.root_device());
for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) for (device_execute_interface *exec = execiter.first(); exec != NULL; exec = execiter.next())
{ {
/* get cpu specific clock that takes internal multiplier/dividers into account */ /* get cpu specific clock that takes internal multiplier/dividers into account */
int clock = exec->device().clock(); int clock = exec->device().clock();
/* count how many identical CPUs we have */ /* count how many identical CPUs we have */
int count = 1; int count = 1;
device_execute_interface *scan = NULL; for (device_execute_interface *scan = execiter.next(); scan != NULL; scan = execiter.next())
for (bool gotanother = exec->next(scan); gotanother; gotanother = scan->next(scan))
{ {
if (exec->device().type() != scan->device().type() || exec->device().clock() != scan->device().clock()) if (exec->device().type() != scan->device().type() || exec->device().clock() != scan->device().clock())
break; break;
count++; count++;
exec = scan; exec = scan;
} }
execiter.set_current(*exec);
/* if more than one, prepend a #x in front of the CPU name */ /* if more than one, prepend a #x in front of the CPU name */
if (count > 1) if (count > 1)
@ -1055,8 +1056,8 @@ astring &game_info_astring(running_machine &machine, astring &string)
} }
/* loop over all sound chips */ /* loop over all sound chips */
device_sound_interface *sound = NULL; sound_interface_iterator snditer(machine.root_device());
for (bool gotone = machine.devicelist().first(sound); gotone; gotone = sound->next(sound)) for (device_sound_interface *sound = snditer.first(); sound != NULL; sound = snditer.next())
{ {
/* append the Sound: string */ /* append the Sound: string */
if (!found_sound) if (!found_sound)
@ -1065,14 +1066,14 @@ astring &game_info_astring(running_machine &machine, astring &string)
/* count how many identical sound chips we have */ /* count how many identical sound chips we have */
int count = 1; int count = 1;
device_sound_interface *scan = NULL; for (device_sound_interface *scan = snditer.next(); scan != NULL; scan = snditer.next())
for (bool gotanother = sound->next(scan); gotanother; gotanother = scan->next(scan))
{ {
if (sound->device().type() != scan->device().type() || sound->device().clock() != scan->device().clock()) if (sound->device().type() != scan->device().type() || sound->device().clock() != scan->device().clock())
break; break;
count++; count++;
sound = scan; sound = scan;
} }
snditer.set_current(*sound);
/* if more than one, prepend a #x in front of the CPU name */ /* if more than one, prepend a #x in front of the CPU name */
if (count > 1) if (count > 1)
@ -1095,7 +1096,8 @@ astring &game_info_astring(running_machine &machine, astring &string)
string.cat("None\n"); string.cat("None\n");
else 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) if (scrcount > 1)
{ {
@ -1271,17 +1273,13 @@ void ui_paste(running_machine &machine)
void ui_image_handler_ingame(running_machine &machine) void ui_image_handler_ingame(running_machine &machine)
{ {
device_image_interface *image = NULL;
/* run display routine for devices */ /* run display routine for devices */
if (machine.phase() == MACHINE_PHASE_RUNNING) 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(); image->call_display();
}
} }
} }
/*------------------------------------------------- /*-------------------------------------------------
@ -1644,7 +1642,6 @@ static slider_state *slider_init(running_machine &machine)
{ {
input_field_config *field; input_field_config *field;
input_port_config *port; input_port_config *port;
device_t *device;
slider_state *listhead = NULL; slider_state *listhead = NULL;
slider_state **tailptr = &listhead; slider_state **tailptr = &listhead;
astring string; astring string;
@ -1683,8 +1680,8 @@ static slider_state *slider_init(running_machine &machine)
/* add CPU overclocking (cheat only) */ /* add CPU overclocking (cheat only) */
if (machine.options().cheat()) if (machine.options().cheat())
{ {
device_execute_interface *exec = NULL; execute_interface_iterator iter(machine.root_device());
for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
{ {
void *param = (void *)&exec->device(); void *param = (void *)&exec->device();
string.printf("Overclock CPU %s", exec->device().tag()); string.printf("Overclock CPU %s", exec->device().tag());
@ -1694,7 +1691,8 @@ static slider_state *slider_init(running_machine &machine)
} }
/* add screen parameters */ /* 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 defxscale = floor(screen->xscale() * 1000.0f + 0.5f);
int defyscale = floor(screen->yscale() * 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; tailptr = &(*tailptr)->next;
} }
for (device = machine.devicelist().first(); device != NULL; device = device->next()) laserdisc_device_iterator lditer(machine.root_device());
{ for (laserdisc_device *laserdisc = lditer.first(); laserdisc != NULL; laserdisc = lditer.next())
laserdisc_device *laserdisc = dynamic_cast<laserdisc_device *>(device); if (laserdisc->overlay_configured())
if (laserdisc != NULL && laserdisc->overlay_configured())
{ {
laserdisc_overlay_config config; laserdisc_overlay_config config;
laserdisc->get_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 = slider_alloc(machine, string, -500, defyoffset, 500, 2, slider_overyoffset, param);
tailptr = &(*tailptr)->next; 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) if (screen->screen_type() == SCREEN_TYPE_VECTOR)
{ {
/* add flicker control */ /* 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) 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]; static char descbuf[256];
if (scrcount > 1) 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() void ui_menu_file_manager::populate()
{ {
char buffer[2048]; char buffer[2048];
device_image_interface *image = NULL;
astring tmp_name; astring tmp_name;
/* cycle through all devices for this system */ /* 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 */ /* get the image type/id */
snprintf(buffer, ARRAY_LENGTH(buffer), 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 ui_menu_mess_tape_control::cassette_count()
{ {
int count = 0; cassette_device_iterator iter(machine().root_device());
device_t *device = machine().devicelist().first(CASSETTE); return iter.count();
while ( device )
{
count++;
device = device->typenext();
}
return count;
} }
/*------------------------------------------------- /*-------------------------------------------------
@ -1018,15 +1011,8 @@ int ui_menu_mess_tape_control::cassette_count()
int ui_menu_mess_bitbanger_control::bitbanger_count() int ui_menu_mess_bitbanger_control::bitbanger_count()
{ {
int count = 0; bitbanger_device_iterator iter(machine().root_device());
device_t *device = machine().devicelist().first(BITBANGER); return iter.count();
while ( device )
{
count++;
device = device->typenext();
}
return count;
} }
/*------------------------------------------------- /*-------------------------------------------------
@ -1197,14 +1183,8 @@ void ui_menu_mess_tape_control::handle()
/* do we have to load the device? */ /* do we have to load the device? */
if (device == NULL) if (device == NULL)
{ {
int cindex = index; cassette_device_iterator iter(machine().root_device());
for (bool gotone = machine().devicelist().first(device); gotone; gotone = device->next(device)) device = iter.byindex(index);
{
if(device->device().type() == CASSETTE) {
if (cindex==0) break;
cindex--;
}
}
reset((ui_menu_reset_options)0); reset((ui_menu_reset_options)0);
} }
@ -1286,14 +1266,8 @@ void ui_menu_mess_bitbanger_control::handle()
/* do we have to load the device? */ /* do we have to load the device? */
if (device == NULL) if (device == NULL)
{ {
int cindex = index; bitbanger_device_iterator iter(machine().root_device());
for (bool gotone = machine().devicelist().first(device); gotone; gotone = device->next(device)) device = iter.byindex(index);
{
if(device->device().type() == BITBANGER) {
if (cindex==0) break;
cindex--;
}
}
reset((ui_menu_reset_options)0); 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()); menu_text.printf("%s Information",emulator_info::get_capstartgamenoun());
item_append(menu_text.cstr(), NULL, 0, (void *)GAME_INFO); item_append(menu_text.cstr(), NULL, 0, (void *)GAME_INFO);
device_image_interface *image = NULL; image_interface_iterator imgiter(machine().root_device());
if (machine().devicelist().first(image)) if (imgiter.first() != NULL)
{ {
/* add image info menu */ /* add image info menu */
item_append("Image Information", NULL, 0, (void *)IMAGE_MENU_IMAGE_INFO); 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); item_append("File Manager", NULL, 0, (void *)IMAGE_MENU_FILE_MANAGER);
/* add tape control menu */ /* 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); item_append("Tape Control", NULL, 0, (void *)MESS_MENU_TAPE_CONTROL);
/* add bitbanger control menu */ /* 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); item_append("Bitbanger Control", NULL, 0, (void *)MESS_MENU_BITBANGER_CONTROL);
} }
device_slot_interface *slot = NULL; slot_interface_iterator slotiter(machine().root_device());
if (machine().devicelist().first(slot)) if (slotiter.first() != NULL)
{ {
/* add image info menu */ /* add image info menu */
item_append("Slot Devices", NULL, 0, (void *)SLOT_DEVICES); item_append("Slot Devices", NULL, 0, (void *)SLOT_DEVICES);
} }
device_network_interface *network = NULL; network_interface_iterator netiter(machine().root_device());
if (machine().devicelist().first(network)) if (netiter.first() != NULL)
{ {
/* add image info menu */ /* add image info menu */
item_append("Network Devices", NULL, 0, (void*)NETWORK_DEVICES); 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() void ui_menu_slot_devices::populate()
{ {
device_slot_interface *slot = NULL;
/* cycle through all devices for this system */ /* 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 */ /* record the menu item */
const char *title = get_slot_device(slot); 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() void ui_menu_network_devices::populate()
{ {
device_network_interface *network = NULL;
/* cycle through all devices for this system */ /* 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(); int curr = network->get_interface();
const char *title = NULL; 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; 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; swlist = _swlist;
interface = _interface; interface = _interface;
@ -171,7 +171,7 @@ ui_menu_software_list::~ui_menu_software_list()
void ui_menu_software_list::populate() 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 // build up the list of entries for the menu
if (list) if (list)
@ -313,7 +313,7 @@ void ui_menu_software_list::handle()
} }
/* list of available software lists - i.e. cartridges, floppies */ /* 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; interface = _interface;
result = _result; result = _result;
@ -324,13 +324,12 @@ void ui_menu_software::populate()
bool haveCompatible = false; bool haveCompatible = false;
// Add original software lists for this system // 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) if (list)
{ {
@ -352,13 +351,11 @@ void ui_menu_software::populate()
} }
// Add compatible software lists for this system // 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) if (list)
{ {
@ -396,7 +393,7 @@ void ui_menu_software::handle()
if (event != NULL && event->iptkey == IPT_UI_SELECT) { 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))); // 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()); ui_menu::stack_pop(machine());
} }
} }

View File

@ -35,7 +35,7 @@ private:
class ui_menu_software_list : public ui_menu { class ui_menu_software_list : public ui_menu {
public: 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 ~ui_menu_software_list();
virtual void populate(); virtual void populate();
virtual void handle(); virtual void handle();
@ -48,7 +48,7 @@ private:
const char *long_name; const char *long_name;
}; };
const software_list_config *swlist; /* currently selected list */ const software_list_device *swlist; /* currently selected list */
const char *interface; const char *interface;
astring &result; astring &result;
entry_info *entrylist; entry_info *entrylist;
@ -61,14 +61,14 @@ private:
class ui_menu_software : public ui_menu { class ui_menu_software : public ui_menu {
public: 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 ~ui_menu_software();
virtual void populate(); virtual void populate();
virtual void handle(); virtual void handle();
private: private:
const char *interface; const char *interface;
const software_list_config **result; const software_list_device **result;
}; };
#endif /* __UISWLIST_H__ */ #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