summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.gitattributes2
-rw-r--r--makefile5
-rw-r--r--src/emu/addrmap.c75
-rw-r--r--src/emu/addrmap.h8
-rw-r--r--src/emu/audit.c66
-rw-r--r--src/emu/cheat.c4
-rw-r--r--src/emu/clifront.c96
-rw-r--r--src/emu/cpu/psx/psx.c13
-rw-r--r--src/emu/cpu/psx/psx.h4
-rw-r--r--src/emu/cpu/tms34010/tms34010.c6
-rw-r--r--src/emu/debug/debugcmd.c78
-rw-r--r--src/emu/debug/debugcpu.c25
-rw-r--r--src/emu/debug/dvdisasm.c4
-rw-r--r--src/emu/debug/dvmemory.c4
-rw-r--r--src/emu/debug/dvstate.c4
-rw-r--r--src/emu/devcb.c12
-rw-r--r--src/emu/devcb.h28
-rw-r--r--src/emu/device.c512
-rw-r--r--src/emu/device.h478
-rw-r--r--src/emu/devlegcy.c7
-rw-r--r--src/emu/devlegcy.h2
-rw-r--r--src/emu/didisasm.h3
-rw-r--r--src/emu/diexec.c67
-rw-r--r--src/emu/diexec.h5
-rw-r--r--src/emu/diimage.c26
-rw-r--r--src/emu/diimage.h11
-rw-r--r--src/emu/dimemory.c104
-rw-r--r--src/emu/dimemory.h5
-rw-r--r--src/emu/dinetwork.h5
-rw-r--r--src/emu/dinvram.h3
-rw-r--r--src/emu/dislot.h7
-rw-r--r--src/emu/disound.c27
-rw-r--r--src/emu/disound.h4
-rw-r--r--src/emu/distate.c2
-rw-r--r--src/emu/distate.h3
-rw-r--r--src/emu/emuopts.c19
-rw-r--r--src/emu/image.c44
-rw-r--r--src/emu/imagedev/bitbngr.h3
-rw-r--r--src/emu/imagedev/cassette.c10
-rw-r--r--src/emu/imagedev/cassette.h3
-rw-r--r--src/emu/info.c60
-rw-r--r--src/emu/ioport.c47
-rw-r--r--src/emu/ioport.h2
-rw-r--r--src/emu/machine.c168
-rw-r--r--src/emu/machine.h47
-rw-r--r--src/emu/machine/6532riot.c3
-rw-r--r--src/emu/machine/7474.c4
-rw-r--r--src/emu/machine/at28c16.c3
-rw-r--r--src/emu/machine/at28c16.h2
-rw-r--r--src/emu/machine/ctronics.c2
-rw-r--r--src/emu/machine/eeprom.c11
-rw-r--r--src/emu/machine/eeprom.h2
-rw-r--r--src/emu/machine/generic.c44
-rw-r--r--src/emu/machine/i2cmem.c4
-rw-r--r--src/emu/machine/i2cmem.h2
-rw-r--r--src/emu/machine/i8243.c6
-rw-r--r--src/emu/machine/laserdsc.h3
-rw-r--r--src/emu/machine/mb3773.c3
-rw-r--r--src/emu/machine/mb3773.h2
-rw-r--r--src/emu/machine/msm6242.c4
-rw-r--r--src/emu/machine/msm6242.h2
-rw-r--r--src/emu/machine/ram.c38
-rw-r--r--src/emu/machine/ram.h5
-rw-r--r--src/emu/machine/rtc9701.c4
-rw-r--r--src/emu/machine/rtc9701.h2
-rw-r--r--src/emu/machine/scsihd.c3
-rw-r--r--src/emu/machine/v3021.c4
-rw-r--r--src/emu/machine/v3021.h2
-rw-r--r--src/emu/machine/wd17xx.c18
-rw-r--r--src/emu/mame.c98
-rw-r--r--src/emu/mame.h10
-rw-r--r--src/emu/mconfig.c135
-rw-r--r--src/emu/mconfig.h13
-rw-r--r--src/emu/memory.c232
-rw-r--r--src/emu/memory.h10
-rw-r--r--src/emu/network.c8
-rw-r--r--src/emu/profiler.c3
-rw-r--r--src/emu/render.c16
-rw-r--r--src/emu/rendlay.c11
-rw-r--r--src/emu/romload.c16
-rw-r--r--src/emu/schedule.c4
-rw-r--r--src/emu/screen.c26
-rw-r--r--src/emu/screen.h6
-rw-r--r--src/emu/softlist.c423
-rw-r--r--src/emu/softlist.h133
-rw-r--r--src/emu/sound.c15
-rw-r--r--src/emu/sound/bsmt2000.c2
-rw-r--r--src/emu/sound/cdda.c5
-rw-r--r--src/emu/sound/disc_inp.c3
-rw-r--r--src/emu/sound/samples.h2
-rw-r--r--src/emu/sound/wave.c6
-rw-r--r--src/emu/speaker.h7
-rw-r--r--src/emu/timer.c34
-rw-r--r--src/emu/timer.h2
-rw-r--r--src/emu/ui.c51
-rw-r--r--src/emu/uiimage.c46
-rw-r--r--src/emu/uimain.c28
-rw-r--r--src/emu/uiswlist.c25
-rw-r--r--src/emu/uiswlist.h8
-rw-r--r--src/emu/validity.c1706
-rw-r--r--src/emu/validity.h123
-rw-r--r--src/emu/video.c27
-rw-r--r--src/emu/video.h2
-rw-r--r--src/emu/video/mc6845.c7
-rw-r--r--src/emu/video/ramdac.c4
-rw-r--r--src/emu/video/ramdac.h2
-rw-r--r--src/emu/video/voodoo.c10
-rw-r--r--src/lib/lib.mak41
-rw-r--r--src/lib/libflac/include/flac/ordinals.h3
-rw-r--r--src/lib/libflac/libflac++.mak23
-rw-r--r--src/lib/libflac/libflac.mak34
-rw-r--r--src/mame/drivers/cliffhgr.c1
-rw-r--r--src/mame/drivers/firebeat.c3
-rw-r--r--src/mame/drivers/merit.c2
-rw-r--r--src/mame/drivers/pinkiri8.c6
-rw-r--r--src/mame/etc/template_device.c5
-rw-r--r--src/mame/etc/template_device.h2
-rw-r--r--src/mame/machine/atarigen.c9
-rw-r--r--src/mame/machine/mie.c2
-rw-r--r--src/mame/machine/psx.c6
-rw-r--r--src/mame/video/cyberbal.c3
-rw-r--r--src/mame/video/gp9001.c4
-rw-r--r--src/mame/video/gp9001.h2
-rw-r--r--src/osd/sdl/drawogl.c6
-rw-r--r--src/osd/windows/d3dhlsl.c14
-rw-r--r--src/osd/windows/debugwin.c23
-rw-r--r--src/osd/windows/winmain.c6
127 files changed, 2858 insertions, 2877 deletions
diff --git a/.gitattributes b/.gitattributes
index 4f5ee594ad5..465d2826e04 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1616,11 +1616,9 @@ src/lib/libflac/include/protected/stream_decoder.h svneol=native#text/plain
src/lib/libflac/include/protected/stream_encoder.h svneol=native#text/plain
src/lib/libflac/include/share/alloc.h svneol=native#text/plain
src/lib/libflac/include/share/utf8.h svneol=native#text/plain
-src/lib/libflac/libflac++.mak svneol=native#text/plain
src/lib/libflac/libflac++/metadata.cpp svneol=native#text/plain
src/lib/libflac/libflac++/stream_decoder.cpp svneol=native#text/plain
src/lib/libflac/libflac++/stream_encoder.cpp svneol=native#text/plain
-src/lib/libflac/libflac.mak svneol=native#text/plain
src/lib/libflac/libflac/bitmath.c svneol=native#text/plain
src/lib/libflac/libflac/bitreader.c svneol=native#text/plain
src/lib/libflac/libflac/bitwriter.c svneol=native#text/plain
diff --git a/makefile b/makefile
index e68136992ff..a7aaf998930 100644
--- a/makefile
+++ b/makefile
@@ -410,6 +410,10 @@ ifdef USE_NETWORK
DEFS += -DUSE_NETWORK
endif
+# need to ensure FLAC functions are statically linked
+DEFS += -DFLAC__NO_DLL
+
+
#-------------------------------------------------
# compile flags
@@ -634,7 +638,6 @@ all: default tools
FLAC_LIB = $(OBJ)/libflac.a $(OBJ)/libflac++.a
-FLAC_LIB = $(OBJ)/libflac.a $(OBJ)/libflac++.a
#-------------------------------------------------
# defines needed by multiple make files
diff --git a/src/emu/addrmap.c b/src/emu/addrmap.c
index 78f6317ceba..e1bd5d7331e 100644
--- a/src/emu/addrmap.c
+++ b/src/emu/addrmap.c
@@ -45,29 +45,6 @@
//**************************************************************************
//-------------------------------------------------
-// set_tag - set the appropriate tag for a device
-//-------------------------------------------------
-
-inline void map_handler_data::set_tag(const device_t &device, const char *tag)
-{
- if (strcmp(tag, DEVICE_SELF) == 0)
- m_tag = device.tag();
- else if (strcmp(tag, DEVICE_SELF_OWNER) == 0)
- {
- assert(device.owner() != NULL);
- m_tag = device.owner()->tag();
- }
- else
- m_tag = device.subtag(m_derived_tag, tag);
-}
-
-
-
-//**************************************************************************
-// ADDRESS MAP ENTRY
-//**************************************************************************
-
-//-------------------------------------------------
// address_map_entry - constructor
//-------------------------------------------------
@@ -132,7 +109,7 @@ void address_map_entry::set_mask(offs_t _mask)
void address_map_entry::set_read_port(const device_t &device, const char *tag)
{
m_read.m_type = AMH_PORT;
- m_read.set_tag(device, tag);
+ device.subtag(m_read.m_tag, tag);
}
@@ -144,7 +121,7 @@ void address_map_entry::set_read_port(const device_t &device, const char *tag)
void address_map_entry::set_write_port(const device_t &device, const char *tag)
{
m_write.m_type = AMH_PORT;
- m_write.set_tag(device, tag);
+ device.subtag(m_write.m_tag, tag);
}
@@ -156,9 +133,9 @@ void address_map_entry::set_write_port(const device_t &device, const char *tag)
void address_map_entry::set_readwrite_port(const device_t &device, const char *tag)
{
m_read.m_type = AMH_PORT;
- m_read.set_tag(device, tag);
+ device.subtag(m_read.m_tag, tag);
m_write.m_type = AMH_PORT;
- m_write.set_tag(device, tag);
+ device.subtag(m_write.m_tag, tag);
}
@@ -170,7 +147,7 @@ void address_map_entry::set_readwrite_port(const device_t &device, const char *t
void address_map_entry::set_read_bank(const device_t &device, const char *tag)
{
m_read.m_type = AMH_BANK;
- m_read.set_tag(device, tag);
+ device.subtag(m_read.m_tag, tag);
}
@@ -182,7 +159,7 @@ void address_map_entry::set_read_bank(const device_t &device, const char *tag)
void address_map_entry::set_write_bank(const device_t &device, const char *tag)
{
m_write.m_type = AMH_BANK;
- m_write.set_tag(device, tag);
+ device.subtag(m_write.m_tag, tag);
}
@@ -194,9 +171,9 @@ void address_map_entry::set_write_bank(const device_t &device, const char *tag)
void address_map_entry::set_readwrite_bank(const device_t &device, const char *tag)
{
m_read.m_type = AMH_BANK;
- m_read.set_tag(device, tag);
+ device.subtag(m_read.m_tag, tag);
m_write.m_type = AMH_BANK;
- m_write.set_tag(device, tag);
+ device.subtag(m_write.m_tag, tag);
}
@@ -213,10 +190,10 @@ void address_map_entry::set_submap(const device_t &device, const char *tag, addr
assert(unitmask_is_appropriate(bits, mask, func.name()));
m_read.m_type = AMH_DEVICE_SUBMAP;
- m_read.set_tag(device, tag);
+ device.subtag(m_read.m_tag, tag);
m_read.m_mask = mask;
m_write.m_type = AMH_DEVICE_SUBMAP;
- m_write.set_tag(device, tag);
+ device.subtag(m_write.m_tag, tag);
m_write.m_mask = mask;
m_submap_delegate = func;
m_submap_bits = bits;
@@ -267,7 +244,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_read.m_bits = 8;
m_read.m_mask = unitmask;
m_read.m_name = string;
- m_read.set_tag(device, tag);
+ device.subtag(m_read.m_tag, tag);
m_rdevice8 = func;
}
@@ -280,7 +257,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_write.m_bits = 8;
m_write.m_mask = unitmask;
m_write.m_name = string;
- m_write.set_tag(device, tag);
+ device.subtag(m_write.m_tag, tag);
m_wdevice8 = func;
}
@@ -300,7 +277,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_read.m_bits = 8;
m_read.m_mask = unitmask;
m_read.m_name = func.name();
- m_read.set_tag(device, tag);
+ device.subtag(m_read.m_tag, tag);
m_rproto8 = func;
}
@@ -313,7 +290,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_write.m_bits = 8;
m_write.m_mask = unitmask;
m_write.m_name = func.name();
- m_write.set_tag(device, tag);
+ device.subtag(m_write.m_tag, tag);
m_wproto8 = func;
}
@@ -369,7 +346,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_read.m_bits = 16;
m_read.m_mask = unitmask;
m_read.m_name = string;
- m_read.set_tag(device, tag);
+ device.subtag(m_read.m_tag, tag);
m_rdevice16 = func;
}
@@ -382,7 +359,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_write.m_bits = 16;
m_write.m_mask = unitmask;
m_write.m_name = string;
- m_write.set_tag(device, tag);
+ device.subtag(m_write.m_tag, tag);
m_wdevice16 = func;
}
@@ -402,7 +379,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_read.m_bits = 16;
m_read.m_mask = unitmask;
m_read.m_name = func.name();
- m_read.set_tag(device, tag);
+ device.subtag(m_read.m_tag, tag);
m_rproto16 = func;
}
@@ -415,7 +392,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_write.m_bits = 16;
m_write.m_mask = unitmask;
m_write.m_name = func.name();
- m_write.set_tag(device, tag);
+ device.subtag(m_write.m_tag, tag);
m_wproto16 = func;
}
@@ -471,7 +448,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_read.m_bits = 32;
m_read.m_mask = unitmask;
m_read.m_name = string;
- m_read.set_tag(device, tag);
+ device.subtag(m_read.m_tag, tag);
m_rdevice32 = func;
}
@@ -484,7 +461,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_write.m_bits = 32;
m_write.m_mask = unitmask;
m_write.m_name = string;
- m_write.set_tag(device, tag);
+ device.subtag(m_write.m_tag, tag);
m_wdevice32 = func;
}
@@ -504,7 +481,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_read.m_bits = 32;
m_read.m_mask = unitmask;
m_read.m_name = func.name();
- m_read.set_tag(device, tag);
+ device.subtag(m_read.m_tag, tag);
m_rproto32 = func;
}
@@ -517,7 +494,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_write.m_bits = 32;
m_write.m_mask = unitmask;
m_write.m_name = func.name();
- m_write.set_tag(device, tag);
+ device.subtag(m_write.m_tag, tag);
m_wproto32 = func;
}
@@ -573,7 +550,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_read.m_bits = 64;
m_read.m_mask = 0;
m_read.m_name = string;
- m_read.set_tag(device, tag);
+ device.subtag(m_read.m_tag, tag);
m_rdevice64 = func;
}
@@ -586,7 +563,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_write.m_bits = 64;
m_write.m_mask = 0;
m_write.m_name = string;
- m_write.set_tag(device, tag);
+ device.subtag(m_write.m_tag, tag);
m_wdevice64 = func;
}
@@ -606,7 +583,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_read.m_bits = 64;
m_read.m_mask = 0;
m_read.m_name = func.name();
- m_read.set_tag(device, tag);
+ device.subtag(m_read.m_tag, tag);
m_rproto64 = func;
}
@@ -619,7 +596,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char
m_write.m_bits = 64;
m_write.m_mask = 0;
m_write.m_name = func.name();
- m_write.set_tag(device, tag);
+ device.subtag(m_write.m_tag, tag);
m_wproto64 = func;
}
diff --git a/src/emu/addrmap.h b/src/emu/addrmap.h
index fb82b2aa769..af1eae23b04 100644
--- a/src/emu/addrmap.h
+++ b/src/emu/addrmap.h
@@ -85,17 +85,13 @@ public:
: m_type(AMH_NONE),
m_bits(0),
m_mask(0),
- m_name(NULL),
- m_tag(NULL) { }
+ m_name(NULL) { }
map_handler_type m_type; // type of the handler
UINT8 m_bits; // width of the handler in bits, or 0 for default
UINT64 m_mask; // mask for which lanes apply
const char * m_name; // name of the handler
- const char * m_tag; // tag pointing to a reference
- astring m_derived_tag; // string used to hold derived names
-
- void set_tag(const device_t &device, const char *tag);
+ astring m_tag; // path to the target tag
};
diff --git a/src/emu/audit.c b/src/emu/audit.c
index 345baccc9e0..bfc4466d977 100644
--- a/src/emu/audit.c
+++ b/src/emu/audit.c
@@ -76,7 +76,7 @@ media_auditor::summary media_auditor::audit_media(const char *validation)
// temporary hack until romload is update: get the driver path and support it for
// all searches
-const char *driverpath = m_enumerator.config().devicelist().find("root")->searchpath();
+const char *driverpath = m_enumerator.config().root_device().searchpath();
// iterate over ROM sources and regions
int found = 0;
@@ -234,49 +234,49 @@ media_auditor::summary media_auditor::audit_samples()
int found = 0;
// iterate over sample entries
- for (const device_t *device = m_enumerator.config().first_device(); device != NULL; device = device->next())
- if (device->type() == SAMPLES)
+ samples_device_iterator iter(m_enumerator.config().root_device());
+ for (samples_device *device = iter.first(); device != NULL; device = iter.next())
+ {
+ const samples_interface *intf = reinterpret_cast<const samples_interface *>(device->static_config());
+ if (intf->samplenames != NULL)
{
- const samples_interface *intf = reinterpret_cast<const samples_interface *>(device->static_config());
- if (intf->samplenames != NULL)
- {
- // by default we just search using the driver name
- astring searchpath(m_enumerator.driver().name);
+ // by default we just search using the driver name
+ astring searchpath(m_enumerator.driver().name);
- // iterate over samples in this entry
- for (int sampnum = 0; intf->samplenames[sampnum] != NULL; sampnum++)
+ // iterate over samples in this entry
+ for (int sampnum = 0; intf->samplenames[sampnum] != NULL; sampnum++)
+ {
+ // starred entries indicate an additional searchpath
+ if (intf->samplenames[sampnum][0] == '*')
{
- // starred entries indicate an additional searchpath
- if (intf->samplenames[sampnum][0] == '*')
- {
- searchpath.cat(";").cat(&intf->samplenames[sampnum][1]);
- continue;
- }
+ searchpath.cat(";").cat(&intf->samplenames[sampnum][1]);
+ continue;
+ }
- required++;
+ required++;
- // create a new record
- audit_record &record = m_record_list.append(*global_alloc(audit_record(intf->samplenames[sampnum], audit_record::MEDIA_SAMPLE)));
+ // create a new record
+ audit_record &record = m_record_list.append(*global_alloc(audit_record(intf->samplenames[sampnum], audit_record::MEDIA_SAMPLE)));
- // look for the files
- emu_file file(m_enumerator.options().sample_path(), OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD);
- path_iterator path(searchpath);
- astring curpath;
- while (path.next(curpath, intf->samplenames[sampnum]))
+ // look for the files
+ emu_file file(m_enumerator.options().sample_path(), OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD);
+ path_iterator path(searchpath);
+ astring curpath;
+ while (path.next(curpath, intf->samplenames[sampnum]))
+ {
+ // attempt to access the file
+ file_error filerr = file.open(curpath);
+ if (filerr == FILERR_NONE)
{
- // attempt to access the file
- file_error filerr = file.open(curpath);
- if (filerr == FILERR_NONE)
- {
- record.set_status(audit_record::STATUS_GOOD, audit_record::SUBSTATUS_GOOD);
- found++;
- }
- else
- record.set_status(audit_record::STATUS_NOT_FOUND, audit_record::SUBSTATUS_NOT_FOUND);
+ record.set_status(audit_record::STATUS_GOOD, audit_record::SUBSTATUS_GOOD);
+ found++;
}
+ else
+ record.set_status(audit_record::STATUS_NOT_FOUND, audit_record::SUBSTATUS_NOT_FOUND);
}
}
}
+ }
if (found == 0 && required > 0)
{
diff --git a/src/emu/cheat.c b/src/emu/cheat.c
index e058398717f..d9939bc2f93 100644
--- a/src/emu/cheat.c
+++ b/src/emu/cheat.c
@@ -1174,8 +1174,8 @@ void cheat_manager::reload()
// load the cheat file, MESS will load a crc32.xml ( eg. 01234567.xml )
// and MAME will load gamename.xml
- device_image_interface *image = NULL;
- for (bool gotone = machine().devicelist().first(image); gotone; gotone = image->next(image))
+ image_interface_iterator iter(machine().root_device());
+ for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
if (image->exists())
{
// if we are loading through software lists, try to load shortname.xml
diff --git a/src/emu/clifront.c b/src/emu/clifront.c
index 00bc2dde8bf..c7339c078ff 100644
--- a/src/emu/clifront.c
+++ b/src/emu/clifront.c
@@ -183,14 +183,14 @@ int cli_frontend::execute(int argc, char **argv)
if (strlen(m_options.software_name()) > 0)
{
machine_config config(*system, m_options);
- if (!config.devicelist().first(SOFTWARE_LIST))
+ software_list_device_iterator iter(config.root_device());
+ if (iter.first() == NULL)
throw emu_fatalerror(MAMERR_FATALERROR, "Error: unknown option: %s\n", m_options.software_name());
bool found = FALSE;
- for (device_t *swlists = config.devicelist().first(SOFTWARE_LIST); swlists != NULL; swlists = swlists->typenext())
+ for (software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next())
{
- software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(swlists)->inline_config();
- software_list *list = software_list_open(m_options, swlist->list_name, FALSE, NULL);
+ software_list *list = software_list_open(m_options, swlist->list_name(), FALSE, NULL);
if (list)
{
software_info *swinfo = software_list_find(list, m_options.software_name(), NULL);
@@ -205,8 +205,8 @@ int cli_frontend::execute(int argc, char **argv)
if (mount == NULL || strcmp(mount,"no") != 0)
{
// search for an image device with the right interface
- const device_image_interface *image = NULL;
- for (bool gotone = config.devicelist().first(image); gotone; gotone = image->next(image))
+ image_interface_iterator imgiter(config.root_device());
+ for (device_image_interface *image = imgiter.first(); image != NULL; image = imgiter.next())
{
const char *interface = image->image_interface();
if (interface != NULL)
@@ -218,7 +218,7 @@ int cli_frontend::execute(int argc, char **argv)
if (strlen(option) == 0)
{
astring val;
- val.printf("%s:%s:%s",swlist->list_name,m_options.software_name(),swpart->name);
+ val.printf("%s:%s:%s",swlist->list_name(),m_options.software_name(),swpart->name);
// call this in order to set slot devices according to mounting
m_options.parse_slot_devices(argc, argv, option_errors, image->instance_name(), val.cstr());
break;
@@ -238,7 +238,7 @@ int cli_frontend::execute(int argc, char **argv)
}
if (!found)
{
- software_display_matches(config.devicelist(),m_options, NULL,m_options.software_name());
+ software_display_matches(config,m_options, NULL,m_options.software_name());
throw emu_fatalerror(MAMERR_FATALERROR, "");
}
}
@@ -551,11 +551,8 @@ void cli_frontend::listsamples(const char *gamename)
while (drivlist.next())
{
// see if we have samples
- const device_t *device;
- for (device = drivlist.config().first_device(); device != NULL; device = device->next())
- if (device->type() == SAMPLES)
- break;
- if (device == NULL)
+ samples_device_iterator iter(drivlist.config().root_device());
+ if (iter.first() == NULL)
continue;
// print a header
@@ -565,16 +562,15 @@ void cli_frontend::listsamples(const char *gamename)
mame_printf_info("Samples required for driver \"%s\".\n", drivlist.driver().name);
// iterate over samples devices
- for ( ; device != NULL; device = device->next())
- if (device->type() == SAMPLES)
- {
- // if the list is legit, walk it and print the sample info
- const char *const *samplenames = reinterpret_cast<const samples_interface *>(device->static_config())->samplenames;
- if (samplenames != NULL)
- for (int sampnum = 0; samplenames[sampnum] != NULL; sampnum++)
- if (samplenames[sampnum][0] != '*')
- mame_printf_info("%s\n", samplenames[sampnum]);
- }
+ for (samples_device *device = iter.first(); device != NULL; device = iter.next())
+ {
+ // if the list is legit, walk it and print the sample info
+ const char *const *samplenames = reinterpret_cast<const samples_interface *>(device->static_config())->samplenames;
+ if (samplenames != NULL)
+ for (int sampnum = 0; samplenames[sampnum] != NULL; sampnum++)
+ if (samplenames[sampnum][0] != '*')
+ mame_printf_info("%s\n", samplenames[sampnum]);
+ }
}
}
@@ -602,7 +598,8 @@ void cli_frontend::listdevices(const char *gamename)
printf("Driver %s (%s):\n", drivlist.driver().name, drivlist.driver().description);
// iterate through devices
- for (const device_t *device = drivlist.config().first_device(); device != NULL; device = device->next())
+ device_iterator iter(drivlist.config().root_device());
+ for (const device_t *device = iter.first(); device != NULL; device = iter.next())
{
printf(" %s ('%s')", device->name(), device->tag());
@@ -642,9 +639,9 @@ void cli_frontend::listslots(const char *gamename)
while (drivlist.next())
{
// iterate
- const device_slot_interface *slot = NULL;
+ slot_interface_iterator iter(drivlist.config().root_device());
bool first = true;
- for (bool gotone = drivlist.config().devicelist().first(slot); gotone; gotone = slot->next(slot))
+ for (const device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next())
{
// output the line, up to the list of extensions
printf("%-13s%-10s ", first ? drivlist.driver().name : "", slot->device().tag());
@@ -653,7 +650,7 @@ void cli_frontend::listslots(const char *gamename)
const slot_interface* intf = slot->get_slot_interfaces();
for (int i = 0; intf[i].name != NULL; i++)
{
- device_t *dev = (*intf[i].devtype)(drivlist.config(), "dummy", drivlist.config().devicelist().first(), 0);
+ device_t *dev = (*intf[i].devtype)(drivlist.config(), "dummy", &drivlist.config().root_device(), 0);
dev->config_complete();
if (i==0) {
printf("%-15s %s\n", intf[i].name,dev->name());
@@ -694,9 +691,9 @@ void cli_frontend::listmedia(const char *gamename)
while (drivlist.next())
{
// iterate
- const device_image_interface *imagedev = NULL;
+ image_interface_iterator iter(drivlist.config().root_device());
bool first = true;
- for (bool gotone = drivlist.config().devicelist().first(imagedev); gotone; gotone = imagedev->next(imagedev))
+ for (const device_image_interface *imagedev = iter.first(); imagedev != NULL; imagedev = iter.next())
{
// extract the shortname with parentheses
astring paren_shortname;
@@ -798,7 +795,7 @@ void cli_frontend::verifyroms(const char *gamename)
driver_enumerator dummy_drivlist(m_options);
dummy_drivlist.next();
machine_config &config = dummy_drivlist.config();
- device_t *owner = config.devicelist().first();
+ device_t *owner = &config.root_device();
// check if all are listed, note that empty one is included
for (int i = 0; i < m_device_count; i++)
{
@@ -994,12 +991,12 @@ void cli_frontend::listsoftware(const char *gamename)
// first determine the maximum number of lists we might encounter
int list_count = 0;
while (drivlist.next())
- for (const device_t *dev = drivlist.config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext())
- {
- software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config();
- if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)
+ {
+ software_list_device_iterator iter(drivlist.config().root_device());
+ for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next())
+ if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM)
list_count++;
- }
+ }
// allocate a list
astring *lists = global_alloc_array(astring, list_count);
@@ -1079,28 +1076,28 @@ void cli_frontend::listsoftware(const char *gamename)
drivlist.reset();
list_count = 0;
while (drivlist.next())
- for (const device_t *dev = drivlist.config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext())
+ {
+ software_list_device_iterator iter(drivlist.config().root_device());
+ for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next())
{
- software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config();
-
- if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)
+ if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM)
{
- software_list *list = software_list_open(m_options, swlist->list_name, FALSE, NULL);
+ software_list *list = software_list_open(m_options, swlist->list_name(), FALSE, NULL);
if ( list )
{
/* Verify if we have encountered this list before */
bool seen_before = false;
for (int seen_index = 0; seen_index < list_count && !seen_before; seen_index++)
- if (lists[seen_index] == swlist->list_name)
+ if (lists[seen_index] == swlist->list_name())
seen_before = true;
if (!seen_before)
{
- lists[list_count++] = swlist->list_name;
+ lists[list_count++] = swlist->list_name();
software_list_parse( list, NULL, NULL );
- fprintf(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlist->list_name, xml_normalize_string(software_list_get_description(list)) );
+ fprintf(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlist->list_name(), xml_normalize_string(software_list_get_description(list)) );
for ( software_info *swinfo = software_list_find( list, "*", NULL ); swinfo != NULL; swinfo = software_list_find( list, "*", swinfo ) )
{
@@ -1239,6 +1236,7 @@ void cli_frontend::listsoftware(const char *gamename)
}
}
}
+ }
if (list_count > 0)
fprintf( out, "</softwarelists>\n" );
@@ -1300,8 +1298,8 @@ void cli_frontend::execute_commands(const char *exename)
// validate?
if (strcmp(m_options.command(), CLICOMMAND_VALIDATE) == 0)
{
- validate_drivers(m_options);
- validate_softlists(m_options);
+ validity_checker valid(m_options);
+ valid.check_all();
return;
}
@@ -1634,10 +1632,10 @@ int media_identifier::find_by_hash(const hash_collection &hashes, int length)
}
// next iterate over softlists
- for (const device_t *dev = m_drivlist.config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext())
+ software_list_device_iterator iter(m_drivlist.config().root_device());
+ for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next())
{
- software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config();
- software_list *list = software_list_open(m_drivlist.options(), swlist->list_name, FALSE, NULL);
+ software_list *list = software_list_open(m_drivlist.options(), swlist->list_name(), FALSE, NULL);
for (software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo))
for (software_part *part = software_find_part(swinfo, NULL, NULL); part != NULL; part = software_part_next(part))
@@ -1652,7 +1650,7 @@ int media_identifier::find_by_hash(const hash_collection &hashes, int length)
// output information about the match
if (found)
mame_printf_info(" ");
- mame_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlist->list_name, swinfo->shortname, swinfo->longname);
+ mame_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlist->list_name(), swinfo->shortname, swinfo->longname);
found++;
}
}
diff --git a/src/emu/cpu/psx/psx.c b/src/emu/cpu/psx/psx.c
index e743ca4ec1e..0795b2180bc 100644
--- a/src/emu/cpu/psx/psx.c
+++ b/src/emu/cpu/psx/psx.c
@@ -3158,29 +3158,24 @@ void psxcpu_device::setcp3cr( int reg, UINT32 value )
psxcpu_device *psxcpu_device::getcpu( device_t &device, const char *cputag )
{
- if( strcmp( cputag, DEVICE_SELF ) == 0 )
- {
- return downcast<psxcpu_device *>( &device );
- }
-
- return downcast<psxcpu_device *>( device.siblingdevice( cputag ) );
+ return downcast<psxcpu_device *>( device.subdevice( cputag ) );
}
void psxcpu_device::irq_set( device_t &device, const char *cputag, UINT32 bitmask )
{
- psxirq_device *irq = downcast<psxirq_device *>( getcpu( device, cputag )->subdevice("irq") );
+ psxirq_device *irq = getcpu( device, cputag )->subdevice<psxirq_device>("irq");
irq->set( bitmask );
}
void psxcpu_device::install_sio_handler( device_t &device, const char *cputag, int n_port, psx_sio_handler p_f_sio_handler )
{
- psxsio_device *sio = downcast<psxsio_device *>( getcpu( device, cputag )->subdevice("sio") );
+ psxsio_device *sio = getcpu( device, cputag )->subdevice<psxsio_device>("sio");
sio->install_handler( n_port, p_f_sio_handler );
}
void psxcpu_device::sio_input( device_t &device, const char *cputag, int n_port, int n_mask, int n_data )
{
- psxsio_device *sio = downcast<psxsio_device *>( getcpu( device, cputag )->subdevice("sio") );
+ psxsio_device *sio = getcpu( device, cputag )->subdevice<psxsio_device>("sio");
sio->input( n_port, n_mask, n_data );
}
diff --git a/src/emu/cpu/psx/psx.h b/src/emu/cpu/psx/psx.h
index 6b5e9349daf..6c984186f5f 100644
--- a/src/emu/cpu/psx/psx.h
+++ b/src/emu/cpu/psx/psx.h
@@ -105,10 +105,10 @@ enum
//**************************************************************************
#define MCFG_PSX_DMA_CHANNEL_READ( cputag, channel, handler ) \
- downcast<psxdma_device *>( psxcpu_device::getcpu( *owner, cputag )->subdevice("dma") )->install_read_handler( channel, handler );
+ psxcpu_device::getcpu( *owner, cputag )->subdevice<psxdma_device>("dma")->install_read_handler( channel, handler );
#define MCFG_PSX_DMA_CHANNEL_WRITE( cputag, channel, handler ) \
- downcast<psxdma_device *>( psxcpu_device::getcpu( *owner, cputag )->subdevice("dma") )->install_write_handler( channel, handler );
+ psxcpu_device::getcpu( *owner, cputag )->subdevice<psxdma_device>("dma")->install_write_handler( channel, handler );
diff --git a/src/emu/cpu/tms34010/tms34010.c b/src/emu/cpu/tms34010/tms34010.c
index 36252211cb4..e6068214e2d 100644
--- a/src/emu/cpu/tms34010/tms34010.c
+++ b/src/emu/cpu/tms34010/tms34010.c
@@ -1087,7 +1087,8 @@ SCREEN_UPDATE_IND16( tms340x0_ind16 )
int x;
/* find the owning CPU */
- for (cpu = screen.machine().devicelist().first(); cpu != NULL; cpu = cpu->next())
+ device_iterator iter(screen.machine().root_device());
+ for (cpu = iter.first(); cpu != NULL; cpu = iter.next())
{
device_type type = cpu->type();
if (type == TMS34010 || type == TMS34020)
@@ -1135,7 +1136,8 @@ SCREEN_UPDATE_RGB32( tms340x0_rgb32 )
int x;
/* find the owning CPU */
- for (cpu = screen.machine().devicelist().first(); cpu != NULL; cpu = cpu->next())
+ device_iterator iter(screen.machine().root_device());
+ for (cpu = iter.first(); cpu != NULL; cpu = iter.next())
{
device_type type = cpu->type();
if (type == TMS34010 || type == TMS34020)
diff --git a/src/emu/debug/debugcmd.c b/src/emu/debug/debugcmd.c
index 5f5606f1968..4711418c06d 100644
--- a/src/emu/debug/debugcmd.c
+++ b/src/emu/debug/debugcmd.c
@@ -391,7 +391,8 @@ void debug_command_init(running_machine &machine)
static void debug_command_exit(running_machine &machine)
{
/* turn off all traces */
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(machine.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
device->debug()->trace(NULL, 0, NULL);
if (cheat.length)
@@ -545,8 +546,8 @@ int debug_command_parameter_cpu(running_machine &machine, const char *param, dev
}
/* if we got a valid one, return */
- device_execute_interface *exec = NULL;
- for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec))
+ execute_interface_iterator iter(machine.root_device());
+ for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
if (cpunum-- == 0)
{
*result = &exec->device();
@@ -982,8 +983,8 @@ static void execute_focus(running_machine &machine, int ref, int params, const c
cpu->debug()->ignore(false);
/* then loop over CPUs and set the ignore flags on all other CPUs */
- device_execute_interface *exec = NULL;
- for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec))
+ execute_interface_iterator iter(machine.root_device());
+ for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
if (&exec->device() != cpu)
exec->device().debug()->ignore(true);
debug_console_printf(machine, "Now focused on CPU '%s'\n", cpu->tag());
@@ -1002,8 +1003,8 @@ static void execute_ignore(running_machine &machine, int ref, int params, const
astring buffer;
/* loop over all executable devices */
- device_execute_interface *exec = NULL;
- for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec))
+ execute_interface_iterator iter(machine.root_device());
+ for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
/* build up a comma-separated list */
if (!exec->device().debug()->observing())
@@ -1034,11 +1035,14 @@ static void execute_ignore(running_machine &machine, int ref, int params, const
for (int paramnum = 0; paramnum < params; paramnum++)
{
/* make sure this isn't the last live CPU */
- device_execute_interface *exec = NULL;
- bool gotone;
- for (gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec))
+ execute_interface_iterator iter(machine.root_device());
+ bool gotone = false;
+ for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
if (&exec->device() != devicelist[paramnum] && exec->device().debug()->observing())
+ {
+ gotone = true;
break;
+ }
if (!gotone)
{
debug_console_printf(machine, "Can't ignore all devices!\n");
@@ -1064,8 +1068,8 @@ static void execute_observe(running_machine &machine, int ref, int params, const
astring buffer;
/* loop over all executable devices */
- device_execute_interface *exec = NULL;
- for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec))
+ execute_interface_iterator iter(machine.root_device());
+ for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
/* build up a comma-separated list */
if (exec->device().debug()->observing())
@@ -1214,7 +1218,8 @@ static void execute_bpclear(running_machine &machine, int ref, int params, const
/* if 0 parameters, clear all */
if (params == 0)
{
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(machine.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
device->debug()->breakpoint_clear_all();
debug_console_printf(machine, "Cleared all breakpoints\n");
}
@@ -1224,8 +1229,9 @@ static void execute_bpclear(running_machine &machine, int ref, int params, const
return;
else
{
+ device_iterator iter(machine.root_device());
bool found = false;
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
if (device->debug()->breakpoint_clear(bpindex))
found = true;
if (found)
@@ -1248,7 +1254,8 @@ static void execute_bpdisenable(running_machine &machine, int ref, int params, c
/* if 0 parameters, clear all */
if (params == 0)
{
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(machine.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
device->debug()->breakpoint_enable_all(ref);
if (ref == 0)
debug_console_printf(machine, "Disabled all breakpoints\n");
@@ -1261,8 +1268,9 @@ static void execute_bpdisenable(running_machine &machine, int ref, int params, c
return;
else
{
+ device_iterator iter(machine.root_device());
bool found = false;
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
if (device->debug()->breakpoint_enable(bpindex, ref))
found = true;
if (found)
@@ -1284,7 +1292,8 @@ static void execute_bplist(running_machine &machine, int ref, int params, const
astring buffer;
/* loop over all CPUs */
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(machine.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
if (device->debug()->breakpoint_first() != NULL)
{
debug_console_printf(machine, "Device '%s' breakpoints:\n", device->tag());
@@ -1372,7 +1381,8 @@ static void execute_wpclear(running_machine &machine, int ref, int params, const
/* if 0 parameters, clear all */
if (params == 0)
{
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(machine.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
device->debug()->watchpoint_clear_all();
debug_console_printf(machine, "Cleared all watchpoints\n");
}
@@ -1382,8 +1392,9 @@ static void execute_wpclear(running_machine &machine, int ref, int params, const
return;
else
{
+ device_iterator iter(machine.root_device());
bool found = false;
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
if (device->debug()->watchpoint_clear(wpindex))
found = true;
if (found)
@@ -1406,7 +1417,8 @@ static void execute_wpdisenable(running_machine &machine, int ref, int params, c
/* if 0 parameters, clear all */
if (params == 0)
{
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(machine.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
device->debug()->watchpoint_enable_all(ref);
if (ref == 0)
debug_console_printf(machine, "Disabled all watchpoints\n");
@@ -1419,8 +1431,9 @@ static void execute_wpdisenable(running_machine &machine, int ref, int params, c
return;
else
{
+ device_iterator iter(machine.root_device());
bool found = false;
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
if (device->debug()->watchpoint_enable(wpindex, ref))
found = true;
if (found)
@@ -1442,7 +1455,8 @@ static void execute_wplist(running_machine &machine, int ref, int params, const
astring buffer;
/* loop over all CPUs */
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(machine.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++)
if (device->debug()->watchpoint_first(spacenum) != NULL)
{
@@ -1484,7 +1498,8 @@ static void execute_hotspot(running_machine &machine, int ref, int params, const
bool cleared = false;
/* loop over CPUs and find live spots */
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(machine.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
if (device->debug()->hotspot_tracking_enabled())
{
device->debug()->hotspot_track(0, 0);
@@ -2498,7 +2513,8 @@ static void execute_snap(running_machine &machine, int ref, int params, const ch
const char *filename = param[0];
int scrnum = (params > 1) ? atoi(param[1]) : 0;
- screen_device *screen = downcast<screen_device *>(machine.devicelist().find(SCREEN, scrnum));
+ screen_device_iterator iter(machine.root_device());
+ screen_device *screen = iter.byindex(scrnum);
if ((screen == NULL) || !machine.render().is_live(*screen))
{
@@ -2682,12 +2698,12 @@ static void execute_hardreset(running_machine &machine, int ref, int params, con
static void execute_images(running_machine &machine, int ref, int params, const char **param)
{
- device_image_interface *img = NULL;
- for (bool gotone = machine.devicelist().first(img); gotone; gotone = img->next(img))
+ image_interface_iterator iter(machine.root_device());
+ for (device_image_interface *img = iter.first(); img != NULL; img = iter.next())
{
debug_console_printf(machine, "%s: %s\n",img->brief_instance_name(),img->exists() ? img->filename() : "[empty slot]");
}
- if (!machine.devicelist().first(img)) {
+ if (iter.first() == NULL) {
debug_console_printf(machine, "No image devices in this driver\n");
}
}
@@ -2698,9 +2714,9 @@ static void execute_images(running_machine &machine, int ref, int params, const
static void execute_mount(running_machine &machine, int ref, int params, const char **param)
{
- device_image_interface *img = NULL;
+ image_interface_iterator iter(machine.root_device());
bool done = false;
- for (bool gotone = machine.devicelist().first(img); gotone; gotone = img->next(img))
+ for (device_image_interface *img = iter.first(); img != NULL; img = iter.next())
{
if (strcmp(img->brief_instance_name(),param[0])==0) {
if (img->load(param[1])==IMAGE_INIT_FAIL) {
@@ -2722,9 +2738,9 @@ static void execute_mount(running_machine &machine, int ref, int params, const c
static void execute_unmount(running_machine &machine, int ref, int params, const char **param)
{
- device_image_interface *img = NULL;
+ image_interface_iterator iter(machine.root_device());
bool done = false;
- for (bool gotone = machine.devicelist().first(img); gotone; gotone = img->next(img))
+ for (device_image_interface *img = iter.first(); img != NULL; img = iter.next())
{
if (strcmp(img->brief_instance_name(),param[0])==0) {
img->unload();
diff --git a/src/emu/debug/debugcpu.c b/src/emu/debug/debugcpu.c
index c4a092dd160..9e46112abf6 100644
--- a/src/emu/debug/debugcpu.c
+++ b/src/emu/debug/debugcpu.c
@@ -201,7 +201,8 @@ void debug_cpu_flush_traces(running_machine &machine)
{
/* this can be called on exit even when no debugging is enabled, so
make sure the devdebug is valid before proceeding */
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(machine.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
if (device->debug() != NULL)
device->debug()->trace_flush();
}
@@ -337,8 +338,9 @@ bool debug_comment_save(running_machine &machine)
xml_set_attribute(systemnode, "name", machine.system().name);
// for each device
+ device_iterator iter(machine.root_device());
bool found_comments = false;
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
if (device->debug()->comment_count() > 0)
{
// create a node for this device
@@ -1081,7 +1083,8 @@ static void on_vblank(running_machine &machine, screen_device &device, bool vbla
static void reset_transient_flags(running_machine &machine)
{
/* loop over CPUs and reset the transient flags */
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(machine.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
device->debug()->reset_transient_flag();
machine.debugcpu_data->m_stop_when_not_device = NULL;
}
@@ -1144,9 +1147,8 @@ static void process_source_file(running_machine &machine)
static device_t *expression_get_device(running_machine &machine, const char *tag)
{
- device_t *device;
-
- for (device = machine.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(machine.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
if (mame_stricmp(device->tag(), tag) == 0)
return device;
@@ -1630,15 +1632,8 @@ static UINT64 get_cpunum(symbol_table &table, void *ref)
running_machine &machine = *reinterpret_cast<running_machine *>(table.globalref());
device_t *target = machine.debugcpu_data->visiblecpu;
- device_execute_interface *exec = NULL;
- int index = 0;
- for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec))
- {
- if (&exec->device() == target)
- return index;
- index++;
- }
- return 0;
+ execute_interface_iterator iter(machine.root_device());
+ return iter.indexof(target->execute());
}
diff --git a/src/emu/debug/dvdisasm.c b/src/emu/debug/dvdisasm.c
index ac3a89a8803..a8041abc168 100644
--- a/src/emu/debug/dvdisasm.c
+++ b/src/emu/debug/dvdisasm.c
@@ -132,9 +132,9 @@ void debug_view_disasm::enumerate_sources()
m_source_list.reset();
// iterate over devices with disassembly interfaces
- device_disasm_interface *dasm = NULL;
+ disasm_interface_iterator iter(machine().root_device());
astring name;
- for (bool gotone = machine().devicelist().first(dasm); gotone; gotone = dasm->next(dasm))
+ for (device_disasm_interface *dasm = iter.first(); dasm != NULL; dasm = iter.next())
{
name.printf("%s '%s'", dasm->device().name(), dasm->device().tag());
m_source_list.append(*auto_alloc(machine(), debug_view_disasm_source(name, dasm->device())));
diff --git a/src/emu/debug/dvmemory.c b/src/emu/debug/dvmemory.c
index a1d4d88f9f8..779e10f256d 100644
--- a/src/emu/debug/dvmemory.c
+++ b/src/emu/debug/dvmemory.c
@@ -152,8 +152,8 @@ void debug_view_memory::enumerate_sources()
astring name;
// first add all the devices' address spaces
- device_memory_interface *memintf = NULL;
- for (bool gotone = machine().devicelist().first(memintf); gotone; gotone = memintf->next(memintf))
+ memory_interface_iterator iter(machine().root_device());
+ for (device_memory_interface *memintf = iter.first(); memintf != NULL; memintf = iter.next())
for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++)
{
address_space *space = memintf->space(spacenum);
diff --git a/src/emu/debug/dvstate.c b/src/emu/debug/dvstate.c
index 9d14f1c83d8..5cbd08091eb 100644
--- a/src/emu/debug/dvstate.c
+++ b/src/emu/debug/dvstate.c
@@ -103,9 +103,9 @@ void debug_view_state::enumerate_sources()
m_source_list.reset();
// iterate over devices that have state interfaces
- device_state_interface *state = NULL;
+ state_interface_iterator iter(machine().root_device());
astring name;
- for (bool gotone = machine().devicelist().first(state); gotone; gotone = state->next(state))
+ for (device_state_interface *state = iter.first(); state != NULL; state = iter.next())
{
name.printf("%s '%s'", state->device().name(), state->device().tag());
m_source_list.append(*auto_alloc(machine(), debug_view_state_source(name, state->device())));
diff --git a/src/emu/devcb.c b/src/emu/devcb.c
index 03c18f75c52..089dcd3388b 100644
--- a/src/emu/devcb.c
+++ b/src/emu/devcb.c
@@ -96,17 +96,7 @@ const input_port_config *devcb_resolver::resolve_port(const char *tag, device_t
device_t *devcb_resolver::resolve_device(int index, const char *tag, device_t &current)
{
- device_t *result = NULL;
-
- if (index == DEVCB_DEVICE_SELF)
- result = &current;
- else if (index == DEVCB_DEVICE_DRIVER)
- result = current.machine().driver_data();
- else if (strcmp(tag, DEVICE_SELF_OWNER) == 0)
- result = current.owner();
- else
- result = current.siblingdevice(tag);
-
+ device_t *result = current.siblingdevice(tag);
if (result == NULL)
throw emu_fatalerror("Unable to resolve device '%s' (requested by callback to %s '%s')", tag, current.name(), current.tag());
return result;
diff --git a/src/emu/devcb.h b/src/emu/devcb.h
index 6ce7c70ca3f..cbb39d4feb9 100644
--- a/src/emu/devcb.h
+++ b/src/emu/devcb.h
@@ -93,14 +93,6 @@ enum
DEVCB_TYPE_CONSTANT // constant value read
};
-// for DEVCB_TYPE_DEVICE, some further differentiation
-enum
-{
- DEVCB_DEVICE_SELF, // ignore 'tag', refers to the device itself
- DEVCB_DEVICE_DRIVER, // ignore 'tag', refers to the driver device
- DEVCB_DEVICE_OTHER // device specified by 'tag'
-};
-
//**************************************************************************
@@ -158,20 +150,20 @@ void devcb_stub16(device_t *device, offs_t offset, UINT16 data)
#define DEVCB_NULL { DEVCB_TYPE_NULL }
// standard line or read/write handlers with the calling device passed
-#define DEVCB_LINE(func) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_SELF, NULL, #func, func, NULL, NULL }
-#define DEVCB_LINE_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_SELF, NULL, #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL }
-#define DEVCB_HANDLER(func) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_SELF, NULL, #func, NULL, func, NULL }
-#define DEVCB_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_SELF, NULL, #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL }
+#define DEVCB_LINE(func) { DEVCB_TYPE_DEVICE, 0, "", #func, func, NULL, NULL }
+#define DEVCB_LINE_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, "", #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL }
+#define DEVCB_HANDLER(func) { DEVCB_TYPE_DEVICE, 0, "", #func, NULL, func, NULL }
+#define DEVCB_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, "", #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL }
// line or read/write handlers for the driver device
-#define DEVCB_DRIVER_LINE_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_DRIVER, NULL, #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL }
-#define DEVCB_DRIVER_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_DRIVER, NULL, #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL }
+#define DEVCB_DRIVER_LINE_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL }
+#define DEVCB_DRIVER_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL }
// line or read/write handlers for another device
-#define DEVCB_DEVICE_LINE(tag,func) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_OTHER, tag, #func, func, NULL, NULL }
-#define DEVCB_DEVICE_LINE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_OTHER, tag, #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL }
-#define DEVCB_DEVICE_HANDLER(tag,func) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_OTHER, tag, #func, NULL, func, NULL }
-#define DEVCB_DEVICE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_OTHER, tag, #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL }
+#define DEVCB_DEVICE_LINE(tag,func) { DEVCB_TYPE_DEVICE, 0, tag, #func, func, NULL, NULL }
+#define DEVCB_DEVICE_LINE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL }
+#define DEVCB_DEVICE_HANDLER(tag,func) { DEVCB_TYPE_DEVICE, 0, tag, #func, NULL, func, NULL }
+#define DEVCB_DEVICE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL }
// constant values
#define DEVCB_CONSTANT(value) { DEVCB_TYPE_CONSTANT, value, NULL, NULL, NULL, NULL }
diff --git a/src/emu/device.c b/src/emu/device.c
index cf974663892..9b166287dc4 100644
--- a/src/emu/device.c
+++ b/src/emu/device.c
@@ -87,234 +87,6 @@ resource_pool &machine_get_pool(running_machine &machine)
//**************************************************************************
-// DEVICE LIST MANAGEMENT
-//**************************************************************************
-
-//-------------------------------------------------
-// device_list - device list constructor
-//-------------------------------------------------
-
-device_list::device_list(resource_pool &pool)
- : tagged_list<device_t>(pool)
-{
-}
-
-
-//-------------------------------------------------
-// set_machine_all - once the machine is created,
-// tell every device about it
-//-------------------------------------------------
-
-void device_list::set_machine_all(running_machine &machine)
-{
- // add exit and reset callbacks
- m_machine = &machine;
-
- // iterate over devices and set their machines as well
- for (device_t *device = first(); device != NULL; device = device->next())
- device->set_machine(machine);
-}
-
-
-//-------------------------------------------------
-// start_all - start all the devices in the
-// list
-//-------------------------------------------------
-
-void device_list::start_all()
-{
- // add exit and reset callbacks
- machine().add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(device_list::reset_all), this));
- machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(device_list::exit), this));
-
- // add pre-save and post-load callbacks
- machine().save().register_presave(save_prepost_delegate(FUNC(device_list::presave_all), this));
- machine().save().register_postload(save_prepost_delegate(FUNC(device_list::postload_all), this));
-
- // start_new_devices does all the necessary work
- start_new_devices();
-}
-
-
-//-------------------------------------------------
-// start_new_devices - start any unstarted devices
-//-------------------------------------------------
-
-void device_list::start_new_devices()
-{
- assert(m_machine != NULL);
-
- // iterate through the devices
- device_t *nextdevice;
- for (device_t *device = first(); device != NULL; device = nextdevice)
- {
- // see if this device is what we want
- nextdevice = device->next();
- if (!device->started())
- {
- // attempt to start the device, catching any expected exceptions
- try
- {
- // if the device doesn't have a machine yet, set it first
- if (device->m_machine == NULL)
- device->set_machine(machine());
-
- // now start the device
- mame_printf_verbose("Starting %s '%s'\n", device->name(), device->tag());
- device->start();
- }
-
- // handle missing dependencies by moving the device to the end
- catch (device_missing_dependencies &)
- {
- // if we're the end, fail
- mame_printf_verbose(" (missing dependencies; rescheduling)\n");
- if (nextdevice == NULL)
- throw emu_fatalerror("Circular dependency in device startup; unable to start %s '%s'\n", device->name(), device->tag());
- detach(*device);
- append(device->tag(), *device);
- }
- }
- }
-}
-
-
-//-------------------------------------------------
-// reset_all - reset all devices in the list
-//-------------------------------------------------
-
-void device_list::reset_all()
-{
- // iterate over devices and reset them
- for (device_t *device = first(); device != NULL; device = device->next())
- device->reset();
-}
-
-
-//-------------------------------------------------
-// stop_all - stop all the devices in the
-// list
-//-------------------------------------------------
-
-void device_list::stop_all()
-{
- // iterate over devices and stop them
- for (device_t *device = first(); device != NULL; device = device->next())
- device->stop();
-
- // leave with no machine
- m_machine = NULL;
-}
-
-
-//-------------------------------------------------
-// first - return the first device of the given
-// type
-//-------------------------------------------------
-
-device_t *device_list::first(device_type type) const
-{
- device_t *cur;
- for (cur = super::first(); cur != NULL && cur->type() != type; cur = cur->next()) ;
- return cur;
-}
-
-
-//-------------------------------------------------
-// count - count the number of devices of the
-// given type
-//-------------------------------------------------
-
-int device_list::count(device_type type) const
-{
- int num = 0;
- for (const device_t *curdev = first(type); curdev != NULL; curdev = curdev->typenext()) num++;
- return num;
-}
-
-
-//-------------------------------------------------
-// indexof - return the index of the given device
-// among its kind
-//-------------------------------------------------
-
-int device_list::indexof(device_type type, device_t &object) const
-{
- int num = 0;
- for (device_t *cur = first(type); cur != NULL; cur = cur->typenext(), num++)
- if (cur == &object) return num;
- return -1;
-}
-
-
-//-------------------------------------------------
-// indexof - return the index of the given device
-// among its kind
-//-------------------------------------------------
-
-int device_list::indexof(device_type type, const char *tag) const
-{
- device_t *object = find(tag);
- return (object != NULL && object->type() == type) ? indexof(type, *object) : -1;
-}
-
-
-//-------------------------------------------------
-// find - find a device by type + index
-//-------------------------------------------------
-
-device_t *device_list::find(device_type type, int index) const
-{
- for (device_t *cur = first(type); cur != NULL; cur = cur->typenext())
- if (index-- == 0) return cur;
- return NULL;
-}
-
-
-//-------------------------------------------------
-// static_exit - tear down all the devices
-//-------------------------------------------------
-
-void device_list::exit()
-{
- // first let the debugger save comments
- if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
- debug_comment_save(machine());
-
- // stop all the devices before we go away
- stop_all();
-
- // then nuke the devices
- reset();
-}
-
-
-//-------------------------------------------------
-// presave_all - tell all the devices we are
-// about to save
-//-------------------------------------------------
-
-void device_list::presave_all()
-{
- for (device_t *device = first(); device != NULL; device = device->next())
- device->pre_save();
-}
-
-
-//-------------------------------------------------
-// postload_all - tell all the devices we just
-// completed a load
-//-------------------------------------------------
-
-void device_list::postload_all()
-{
- for (device_t *device = first(); device != NULL; device = device->next())
- device->post_load();
-}
-
-
-
-//**************************************************************************
// LIVE DEVICE MANAGEMENT
//**************************************************************************
@@ -325,63 +97,75 @@ void device_list::postload_all()
//-------------------------------------------------
device_t::device_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
- : m_debug(NULL),
+ : m_type(type),
+ m_name(name),
+ m_owner(owner),
+ m_next(NULL),
+ m_interface_list(NULL),
m_execute(NULL),
m_memory(NULL),
m_state(NULL),
- m_next(NULL),
- m_owner(owner),
- m_interface_list(NULL),
- m_type(type),
m_configured_clock(clock),
- m_machine_config(mconfig),
- m_static_config(NULL),
- m_input_defaults(NULL),
- m_name(name),
- m_started(false),
- m_clock(clock),
- m_region(NULL),
m_unscaled_clock(clock),
+ m_clock(clock),
m_clock_scale(1.0),
m_attoseconds_per_clock((clock == 0) ? 0 : HZ_TO_ATTOSECONDS(clock)),
+
+ m_debug(NULL),
+ m_region(NULL),
+ m_machine_config(mconfig),
+ m_static_config(NULL),
+ m_input_defaults(NULL),
m_auto_finder_list(NULL),
m_machine(NULL),
m_save(NULL),
- m_tag(tag),
- m_config_complete(false)
+ m_basetag(tag),
+ m_config_complete(false),
+ m_started(false)
{
+ if (owner != NULL)
+ m_tag.cpy((owner->owner() == NULL) ? "" : owner->tag()).cat(":").cat(tag);
+ else
+ m_tag.cpy(":");
+ mame_printf_verbose("device '%s' created\n", this->tag());
static_set_clock(*this, clock);
}
device_t::device_t(const machine_config &mconfig, device_type type, const char *name, const char *shortname, const char *tag, device_t *owner, UINT32 clock)
- : m_debug(NULL),
+ : m_type(type),
+ m_name(name),
+ m_shortname(shortname),
+ m_searchpath(shortname),
+ m_owner(owner),
+ m_next(NULL),
+ m_interface_list(NULL),
m_execute(NULL),
m_memory(NULL),
m_state(NULL),
- m_next(NULL),
- m_owner(owner),
- m_interface_list(NULL),
- m_type(type),
m_configured_clock(clock),
- m_machine_config(mconfig),
- m_static_config(NULL),
- m_input_defaults(NULL),
- m_name(name),
- m_shortname(shortname),
- m_searchpath(shortname),
- m_started(false),
- m_clock(clock),
- m_region(NULL),
m_unscaled_clock(clock),
+ m_clock(clock),
m_clock_scale(1.0),
m_attoseconds_per_clock((clock == 0) ? 0 : HZ_TO_ATTOSECONDS(clock)),
+
+ m_debug(NULL),
+ m_region(NULL),
+ m_machine_config(mconfig),
+ m_static_config(NULL),
+ m_input_defaults(NULL),
m_auto_finder_list(NULL),
m_machine(NULL),
m_save(NULL),
- m_tag(tag),
- m_config_complete(false)
+ m_basetag(tag),
+ m_config_complete(false),
+ m_started(false)
{
+ if (owner != NULL)
+ m_tag.cpy((owner->owner() == NULL) ? "" : owner->tag()).cat(":").cat(tag);
+ else
+ m_tag.cpy(":");
+ mame_printf_verbose("device '%s' created\n", this->tag());
static_set_clock(*this, clock);
}
@@ -406,43 +190,9 @@ const memory_region *device_t::subregion(const char *_tag) const
if (this == NULL)
return NULL;
- // build a fully-qualified name
- astring tempstring;
- return machine().region(subtag(tempstring, _tag));
-}
-
-
-//-------------------------------------------------
-// subdevice - return a pointer to the given
-// device that is owned by us
-//-------------------------------------------------
-
-device_t *device_t::subdevice(const char *_tag) const
-{
- // safety first
- if (this == NULL)
- return NULL;
-
- // build a fully-qualified name
- astring tempstring;
- return mconfig().devicelist().find((const char *)subtag(tempstring, _tag));
-}
-
-
-//-------------------------------------------------
-// siblingdevice - return a pointer to the given
-// device that is owned by our same owner
-//-------------------------------------------------
-
-device_t *device_t::siblingdevice(const char *_tag) const
-{
- // safety first
- if (this == NULL)
- return NULL;
-
- // build a fully-qualified name
- astring tempstring;
- return mconfig().devicelist().find((const char *)siblingtag(tempstring, _tag));
+ // build a fully-qualified name and look it up
+ astring fullpath;
+ return machine().region(subtag(fullpath, _tag));
}
@@ -489,20 +239,14 @@ void device_t::config_complete()
// configuration has been constructed
//-------------------------------------------------
-bool device_t::validity_check(emu_options &options, const game_driver &driver) const
+void device_t::validity_check(validity_checker &valid) const
{
- bool error = false;
-
// validate via the interfaces
for (device_interface *intf = m_interface_list; intf != NULL; intf = intf->interface_next())
- if (intf->interface_validity_check(options, driver))
- error = true;
+ intf->interface_validity_check(valid);
// let the device itself validate
- if (device_validity_check(options, driver))
- error = true;
-
- return error;
+ device_validity_check(valid);
}
@@ -780,10 +524,9 @@ void device_t::device_config_complete()
// the configuration has been constructed
//-------------------------------------------------
-bool device_t::device_validity_check(emu_options &options, const game_driver &driver) const
+void device_t::device_validity_check(validity_checker &valid) const
{
- // indicate no error by default
- return false;
+ // do nothing by default
}
@@ -812,7 +555,6 @@ machine_config_constructor device_t::device_mconfig_additions() const
}
-
//-------------------------------------------------
// input_ports - return a pointer to the implicit
// input ports description for this device
@@ -908,6 +650,157 @@ void device_t::device_timer(emu_timer &timer, device_timer_id id, int param, voi
//-------------------------------------------------
+// subdevice_slow - perform a slow name lookup,
+// caching the results
+//-------------------------------------------------
+
+device_t *device_t::subdevice_slow(const char *tag) const
+{
+ // resolve the full path
+ astring fulltag;
+ subtag(fulltag, tag);
+
+ // we presume the result is a rooted path; also doubled colons mess up our
+ // tree walk, so catch them early
+ assert(fulltag[0] == ':');
+ assert(fulltag.find("::") == -1);
+
+ // walk the device list to the final path
+ device_t *curdevice = &mconfig().root_device();
+ if (fulltag.len() > 1)
+ for (int start = 1, end = fulltag.chr(start, ':'); start != 0 && curdevice != NULL; start = end + 1, end = fulltag.chr(start, ':'))
+ {
+ astring part(fulltag, start, (end == -1) ? -1 : end - start);
+ for (curdevice = curdevice->m_subdevice_list.first(); curdevice != NULL; curdevice = curdevice->next())
+ if (part == curdevice->m_basetag)
+ break;
+ }
+
+ // if we got a match, add to the fast map
+ if (curdevice != NULL)
+ {
+ m_device_map.add(tag, curdevice);
+ mame_printf_verbose("device '%s' adding mapping for '%s' => '%s'\n", this->tag(), tag, fulltag.cstr());
+ }
+ return curdevice;
+}
+
+
+//-------------------------------------------------
+// subtag - create a fully resolved path relative
+// to our device based on the provided tag
+//-------------------------------------------------
+
+astring &device_t::subtag(astring &result, const char *tag) const
+{
+ // if the tag begins with a colon, ignore our path and start from the root
+ if (*tag == ':')
+ {
+ tag++;
+ result.cpy(":");
+ }
+
+ // otherwise, start with our path
+ else
+ {
+ result.cpy(m_tag);
+ if (result != ":")
+ result.cat(":");
+ }
+
+ // iterate over the tag, look for special path characters to resolve
+ const char *caret;
+ while ((caret = strchr(tag, '^')) != NULL)
+ {
+ // copy everything up to there
+ result.cat(tag, caret - tag);
+ tag = caret + 1;
+
+ // strip trailing colons
+ int len = result.len();
+ while (result[--len] == ':')
+ result.substr(0, len);
+
+ // remove the last path part, leaving the last colon
+ if (result != ":")
+ {
+ int lastcolon = result.rchr(0, ':');
+ if (lastcolon != -1)
+ result.substr(0, lastcolon + 1);
+ }
+ }
+
+ // copy everything else
+ result.cat(tag);
+
+ // strip trailing colons up to the root
+ int len = result.len();
+ while (len > 1 && result[--len] == ':')
+ result.substr(0, len);
+ return result;
+}
+
+
+//-------------------------------------------------
+// add_subdevice - create a new device and add it
+// as a subdevice
+//-------------------------------------------------
+
+device_t *device_t::add_subdevice(device_type type, const char *tag, UINT32 clock)
+{
+ // allocate the device and append to our list
+ device_t *device = (*type)(mconfig(), tag, this, clock);
+ m_subdevice_list.append(*device);
+
+ // apply any machine configuration owned by the device now
+ machine_config_constructor additions = device->machine_config_additions();
+ if (additions != NULL)
+ (*additions)(const_cast<machine_config &>(mconfig()), device);
+ return device;
+}
+
+
+//-------------------------------------------------
+// add_subdevice - create a new device and use it
+// to replace an existing subdevice
+//-------------------------------------------------
+
+device_t *device_t::replace_subdevice(device_t &old, device_type type, const char *tag, UINT32 clock)
+{
+ // iterate over all devices and remove any references to the old device
+ device_iterator iter(mconfig().root_device());
+ for (device_t *scan = iter.first(); scan != NULL; scan = iter.next())
+ scan->m_device_map.remove(&old);
+
+ // create a new device, and substitute it for the old one
+ device_t *device = (*type)(mconfig(), tag, this, clock);
+ m_subdevice_list.replace_and_remove(*device, old);
+
+ // apply any machine configuration owned by the device now
+ machine_config_constructor additions = device->machine_config_additions();
+ if (additions != NULL)
+ (*additions)(const_cast<machine_config &>(mconfig()), device);
+ return device;
+}
+
+
+//-------------------------------------------------
+// remove_subdevice - remove a given subdevice
+//-------------------------------------------------
+
+void device_t::remove_subdevice(device_t &device)
+{
+ // iterate over all devices and remove any references
+ device_iterator iter(mconfig().root_device());
+ for (device_t *scan = iter.first(); scan != NULL; scan = iter.next())
+ scan->m_device_map.remove(&device);
+
+ // remove from our list
+ m_subdevice_list.remove(device);
+}
+
+
+//-------------------------------------------------
// register_auto_finder - add a new item to the
// list of stuff to find after we go live
//-------------------------------------------------
@@ -1022,9 +915,8 @@ void device_interface::interface_config_complete()
// constructed
//-------------------------------------------------
-bool device_interface::interface_validity_check(emu_options &options, const game_driver &driver) const
+void device_interface::interface_validity_check(validity_checker &valid) const
{
- return false;
}
diff --git a/src/emu/device.h b/src/emu/device.h
index a1028944b20..4be5c1c1170 100644
--- a/src/emu/device.h
+++ b/src/emu/device.h
@@ -91,41 +91,13 @@ class device_interface;
class device_execute_interface;
class device_memory_interface;
class device_state_interface;
+class validity_checker;
struct rom_entry;
class machine_config;
class emu_timer;
typedef struct _input_device_default input_device_default;
-// ======================> device_delegate
-
-// device_delegate is a delegate that wraps with a device tag and can be easily
-// late bound without replicating logic everywhere
-template<typename _Signature>
-class device_delegate : public delegate<_Signature>
-{
- typedef delegate<_Signature> basetype;
-
-public:
- // provide same set of constructors as the base class, with additional device name
- // parameter
- device_delegate() : basetype(), m_device_name(NULL) { }
- device_delegate(const basetype &src) : basetype(src), m_device_name(src.m_device_name) { }
- device_delegate(const basetype &src, delegate_late_bind &object) : basetype(src, object), m_device_name(src.m_device_name) { }
- template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname) : basetype(funcptr, name, (_FunctionClass *)0), m_device_name(devname) { }
- template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname, _FunctionClass *object) : basetype(funcptr, name, (_FunctionClass *)0), m_device_name(devname) { }
- device_delegate(typename basetype::template traits<device_t>::static_func_type funcptr, const char *name) : basetype(funcptr, name, (device_t *)0), m_device_name(NULL) { }
- device_delegate(typename basetype::template traits<device_t>::static_ref_func_type funcptr, const char *name) : basetype(funcptr, name, (device_t *)0), m_device_name(NULL) { }
- device_delegate &operator=(const basetype &src) { *static_cast<basetype *>(this) = src; m_device_name = src.m_device_name; return *this; }
-
- // perform the binding
- void bind_relative_to(device_t &search_root);
-
-private:
- // internal state
- const char *m_device_name;
-};
-
// exception classes
class device_missing_dependencies : public emu_exception { };
@@ -153,56 +125,6 @@ typedef void (*write_line_device_func)(device_t *device, int state);
-// ======================> tagged_device_list
-
-// tagged_device_list is a tagged_list with additional searching based on type
-class device_list : public tagged_list<device_t>
-{
- typedef tagged_list<device_t> super;
-
-public:
- // construction/destruction
- device_list(resource_pool &pool = global_resource_pool);
-
- // getters
- running_machine &machine() const { assert(m_machine != NULL); return *m_machine; }
-
- // bulk operations
- void set_machine_all(running_machine &machine);
- void start_all();
- void start_new_devices();
- void reset_all();
- void stop_all();
-
- // pull the generic forms forward
- using super::first;
- using super::count;
- using super::indexof;
- using super::find;
-
- // provide type-specific overrides
- device_t *first(device_type type) const;
- int count(device_type type) const;
- int indexof(device_type type, device_t &object) const;
- int indexof(device_type type, const char *tag) const;
- device_t *find(device_type type, int index) const;
-
- // provide interface-specific overrides
- template<class _InterfaceClass>
- bool first(_InterfaceClass *&intf) const;
-
-private:
- // internal helpers
- void exit();
- void presave_all();
- void postload_all();
-
- // internal state
- running_machine *m_machine;
-};
-
-
-
// ======================> device_t
// device_t represents a device
@@ -216,6 +138,8 @@ class device_t : public delegate_late_bind
friend class device_execute_interface;
friend class simple_list<device_t>;
friend class device_list;
+ friend class machine_config;
+ friend class running_machine;
protected:
// construction/destruction
@@ -226,12 +150,15 @@ protected:
public:
// getters
running_machine &machine() const { assert(m_machine != NULL); return *m_machine; }
+ const char *tag() const { return m_tag; }
+ const char *basetag() const { return m_basetag; }
device_type type() const { return m_type; }
- UINT32 configured_clock() const { return m_configured_clock; }
const char *name() const { return m_name; }
const char *shortname() const { return m_shortname; }
const char *searchpath() const { return m_searchpath; }
- const char *tag() const { return m_tag; }
+ device_t *owner() const { return m_owner; }
+ device_t *next() const { return m_next; }
+ UINT32 configured_clock() const { return m_configured_clock; }
const void *static_config() const { return m_static_config; }
const machine_config &mconfig() const { return m_machine_config; }
const input_device_default *input_ports_defaults() const { return m_input_defaults; }
@@ -239,21 +166,9 @@ public:
machine_config_constructor machine_config_additions() const { return device_mconfig_additions(); }
ioport_constructor input_ports() const { return device_input_ports(); }
- // iteration helpers
- device_t *next() const { return m_next; }
- device_t *typenext() const;
- device_t *owner() const { return m_owner; }
-
// interface helpers
template<class _DeviceClass> bool interface(_DeviceClass *&intf) { intf = dynamic_cast<_DeviceClass *>(this); return (intf != NULL); }
template<class _DeviceClass> bool interface(_DeviceClass *&intf) const { intf = dynamic_cast<const _DeviceClass *>(this); return (intf != NULL); }
- template<class _DeviceClass> bool next(_DeviceClass *&intf) const
- {
- for (device_t *cur = m_next; cur != NULL; cur = cur->m_next)
- if (cur->interface(intf))
- return true;
- return false;
- }
// specialized helpers for common core interfaces
bool interface(device_execute_interface *&intf) { intf = m_execute; return (intf != NULL); }
@@ -266,13 +181,14 @@ public:
device_memory_interface &memory() const { assert(m_memory != NULL); return *m_memory; }
// owned object helpers
+ device_t *first_subdevice() const { return m_subdevice_list.first(); }
astring &subtag(astring &dest, const char *tag) const;
- astring &siblingtag(astring &dest, const char *tag) const;
+ astring &siblingtag(astring &dest, const char *tag) const { return (this != NULL && m_owner != NULL) ? m_owner->subtag(dest, tag) : dest.cpy(tag); }
const memory_region *subregion(const char *tag) const;
device_t *subdevice(const char *tag) const;
- device_t *siblingdevice(const char *tag) const;
- template<class _DeviceClass> inline _DeviceClass *subdevice(const char *tag) { return downcast<_DeviceClass *>(subdevice(tag)); }
- template<class _DeviceClass> inline _DeviceClass *siblingdevice(const char *tag) { return downcast<_DeviceClass *>(siblingdevice(tag)); }
+ device_t *siblingdevice(const char *tag) const { return (this != NULL && m_owner != NULL) ? m_owner->subdevice(tag) : NULL; }
+ template<class _DeviceClass> inline _DeviceClass *subdevice(const char *tag) const { return downcast<_DeviceClass *>(subdevice(tag)); }
+ template<class _DeviceClass> inline _DeviceClass *siblingdevice(const char *tag) const { return downcast<_DeviceClass *>(siblingdevice(tag)); }
const memory_region *region() const { return m_region; }
// configuration helpers
@@ -283,7 +199,7 @@ public:
// state helpers
void config_complete();
bool configured() const { return m_config_complete; }
- bool validity_check(emu_options &options, const game_driver &driver) const;
+ void validity_check(validity_checker &valid) const;
bool started() const { return m_started; }
void reset();
@@ -328,7 +244,7 @@ protected:
virtual machine_config_constructor device_mconfig_additions() const;
virtual ioport_constructor device_input_ports() const;
virtual void device_config_complete();
- virtual bool device_validity_check(emu_options &options, const game_driver &driver) const ATTR_COLD;
+ virtual void device_validity_check(validity_checker &valid) const ATTR_COLD;
virtual void device_start() ATTR_COLD = 0;
virtual void device_stop() ATTR_COLD;
virtual void device_reset() ATTR_COLD;
@@ -340,37 +256,37 @@ protected:
//------------------- end derived class overrides
- device_debug * m_debug;
-
- // core device interfaces for speed
- device_execute_interface *m_execute;
- device_memory_interface *m_memory;
- device_state_interface *m_state;
+ // core device properties
+ const device_type m_type; // device type
+ astring m_name; // name of the device
+ astring m_shortname; // short name of the device
+ astring m_searchpath; // search path, used for media loading
// device relationships
- device_t * m_next; // next device (of any type/class)
- device_t * m_owner; // device that owns us, or NULL if nobody
+ device_t * m_owner; // device that owns us
+ device_t * m_next; // next device by the same owner (of any type/class)
+ simple_list<device_t> m_subdevice_list; // list of sub-devices we own
+ mutable tagmap_t<device_t *> m_device_map; // map of device names looked up and found
+
+ // device interfaces
device_interface * m_interface_list; // head of interface list
+ device_execute_interface *m_execute; // pre-cached pointer to execute interface
+ device_memory_interface *m_memory; // pre-cached pointer to memory interface
+ device_state_interface *m_state; // pre-cached pointer to state interface
- const device_type m_type; // device type
+ // device clocks
UINT32 m_configured_clock; // originally configured device clock
+ UINT32 m_unscaled_clock; // current unscaled device clock
+ UINT32 m_clock; // current device clock, after scaling
+ double m_clock_scale; // clock scale factor
+ attoseconds_t m_attoseconds_per_clock;// period in attoseconds
+ device_debug * m_debug;
+ const memory_region * m_region; // our device-local region
const machine_config & m_machine_config; // reference to the machine's configuration
const void * m_static_config; // static device configuration
const input_device_default *m_input_defaults; // devices input ports default overrides
- astring m_name; // name of the device
- astring m_shortname; // short name of the device
- astring m_searchpath; // search path, used for media loading
-
- bool m_started; // true if the start function has succeeded
- UINT32 m_clock; // device clock
- const memory_region * m_region; // our device-local region
-
- UINT32 m_unscaled_clock; // unscaled clock
- double m_clock_scale; // clock scale factor
- attoseconds_t m_attoseconds_per_clock;// period in attoseconds
-
// helper class to request auto-object discovery in the constructor of a derived class
class auto_finder_base
{
@@ -480,11 +396,19 @@ protected:
auto_finder_base * m_auto_finder_list;
private:
+ // private helpers
+ device_t *add_subdevice(device_type type, const char *tag, UINT32 clock);
+ device_t *replace_subdevice(device_t &old, device_type type, const char *tag, UINT32 clock);
+ void remove_subdevice(device_t &device);
+ device_t *subdevice_slow(const char *tag) const;
+
// private state; accessor use required
running_machine * m_machine;
save_manager * m_save;
- astring m_tag; // tag for this instance
+ astring m_tag; // full tag for this instance
+ astring m_basetag; // base part of the tag
bool m_config_complete; // have we completed our configuration?
+ bool m_started; // true if the start function has succeeded
};
@@ -514,7 +438,7 @@ public:
// optional operation overrides
virtual void interface_config_complete();
- virtual bool interface_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void interface_validity_check(validity_checker &valid) const;
virtual void interface_pre_start();
virtual void interface_post_start();
virtual void interface_pre_reset();
@@ -533,48 +457,299 @@ protected:
};
+// ======================> device_iterator
-//**************************************************************************
-// INLINE FUNCTIONS
-//**************************************************************************
+// helper class to iterate over the hierarchy of devices depth-first
+class device_iterator
+{
+public:
+ // construction
+ device_iterator(device_t &root, int maxdepth = 255)
+ : m_root(&root),
+ m_current(NULL),
+ m_curdepth(0),
+ m_maxdepth(maxdepth) { }
+
+ // getters
+ device_t *current() const { return m_current; }
+ // setters
+ void set_current(device_t &current) { m_current = &current; }
+
+ // reset and return first item
+ device_t *first()
+ {
+ m_current = m_root;
+ return m_current;
+ }
-// ======================> device config helpers
+ // advance depth-first
+ device_t *next()
+ {
+ // remember our starting position, and end immediately if we're NULL
+ device_t *start = m_current;
+ if (start == NULL)
+ return NULL;
-// find the next device_t of the same type
-inline device_t *device_t::typenext() const
+ // search down first
+ if (m_curdepth < m_maxdepth)
+ {
+ m_current = start->first_subdevice();
+ if (m_current != NULL)
+ {
+ m_curdepth++;
+ return m_current;
+ }
+ }
+
+ // search next for neighbors up the ownership chain
+ while (m_curdepth > 0)
+ {
+ // found a neighbor? great!
+ m_current = start->next();
+ if (m_current != NULL)
+ return m_current;
+
+ // no? try our parent
+ start = start->owner();
+ m_curdepth--;
+ }
+
+ // returned to the top; we're done
+ return m_current = NULL;
+ }
+
+ // return the number of items available
+ int count()
+ {
+ int result = 0;
+ for (device_t *item = first(); item != NULL; item = next())
+ result++;
+ return result;
+ }
+
+ // return the index of a given item in the virtual list
+ int indexof(device_t &device)
+ {
+ int index = 0;
+ for (device_t *item = first(); item != NULL; item = next(), index++)
+ if (item == &device)
+ return index;
+ return -1;
+ }
+
+ // return the indexed item in the list
+ device_t *byindex(int index)
+ {
+ for (device_t *item = first(); item != NULL; item = next(), index--)
+ if (index == 0)
+ return item;
+ return NULL;
+ }
+
+private:
+ // internal state
+ device_t * m_root;
+ device_t * m_current;
+ int m_curdepth;
+ int m_maxdepth;
+};
+
+
+// ======================> device_type_iterator
+
+// helper class to find devices of a given type in the device hierarchy
+template<device_type _DeviceType, class _DeviceClass = device_t>
+class device_type_iterator
{
- device_t *cur;
- for (cur = m_next; cur != NULL && cur->m_type != m_type; cur = cur->m_next) ;
- return cur;
-}
+public:
+ // construction
+ device_type_iterator(device_t &root, int maxdepth = 255)
+ : m_iterator(root, maxdepth) { }
+
+ // getters
+ _DeviceClass *current() const { return downcast<_DeviceClass *>(m_iterator.current()); }
+
+ // setters
+ void set_current(_DeviceClass &current) { m_iterator.set_current(current); }
-// create a tag for an object that is owned by this device
-inline astring &device_t::subtag(astring &dest, const char *_tag) const
+ // reset and return first item
+ _DeviceClass *first()
+ {
+ for (device_t *device = m_iterator.first(); device != NULL; device = m_iterator.next())
+ if (device->type() == _DeviceType)
+ return downcast<_DeviceClass *>(device);
+ return NULL;
+ }
+
+ // advance depth-first
+ _DeviceClass *next()
+ {
+ for (device_t *device = m_iterator.next(); device != NULL; device = m_iterator.next())
+ if (device->type() == _DeviceType)
+ return downcast<_DeviceClass *>(device);
+ return NULL;
+ }
+
+ // return the number of items available
+ int count()
+ {
+ int result = 0;
+ for (_DeviceClass *item = first(); item != NULL; item = next())
+ result++;
+ return result;
+ }
+
+ // return the index of a given item in the virtual list
+ int indexof(_DeviceClass &device)
+ {
+ int index = 0;
+ for (_DeviceClass *item = first(); item != NULL; item = next(), index++)
+ if (item == &device)
+ return index;
+ return -1;
+ }
+
+ // return the indexed item in the list
+ _DeviceClass *byindex(int index)
+ {
+ for (_DeviceClass *item = first(); item != NULL; item = next(), index--)
+ if (index == 0)
+ return item;
+ return NULL;
+ }
+
+private:
+ // internal state
+ device_iterator m_iterator;
+};
+
+
+// ======================> device_interface_iterator
+
+// helper class to find devices with a given interface in the device hierarchy
+// also works for findnig devices derived from a given subclass
+template<class _InterfaceClass>
+class device_interface_iterator
{
- // temp. for now: don't include the root tag in the full tag name
- return (this != NULL && m_owner != NULL) ? dest.cpy(m_tag).cat(":").cat(_tag) : dest.cpy(_tag);
-}
+public:
+ // construction
+ device_interface_iterator(device_t &root, int maxdepth = 255)
+ : m_iterator(root, maxdepth),
+ m_current(NULL) { }
+
+ // getters
+ _InterfaceClass *current() const { return m_current; }
+
+ // setters
+ void set_current(_InterfaceClass &current) { m_current = &current; m_iterator.set_current(current.device()); }
-// create a tag for an object that a sibling to this device
-inline astring &device_t::siblingtag(astring &dest, const char *_tag) const
+ // reset and return first item
+ _InterfaceClass *first()
+ {
+ for (device_t *device = m_iterator.first(); device != NULL; device = m_iterator.next())
+ if (device->interface(m_current))
+ return m_current;
+ return NULL;
+ }
+
+ // advance depth-first
+ _InterfaceClass *next()
+ {
+ for (device_t *device = m_iterator.next(); device != NULL; device = m_iterator.next())
+ if (device->interface(m_current))
+ return m_current;
+ return NULL;
+ }
+
+ // return the number of items available
+ int count()
+ {
+ int result = 0;
+ for (_InterfaceClass *item = first(); item != NULL; item = next())
+ result++;
+ return result;
+ }
+
+ // return the index of a given item in the virtual list
+ int indexof(_InterfaceClass &intrf)
+ {
+ int index = 0;
+ for (_InterfaceClass *item = first(); item != NULL; item = next(), index++)
+ if (item == &intrf)
+ return index;
+ return -1;
+ }
+
+ // return the indexed item in the list
+ _InterfaceClass *byindex(int index)
+ {
+ for (_InterfaceClass *item = first(); item != NULL; item = next(), index--)
+ if (index == 0)
+ return item;
+ return NULL;
+ }
+
+private:
+ // internal state
+ device_iterator m_iterator;
+ _InterfaceClass * m_current;
+};
+
+
+// ======================> device_delegate
+
+// device_delegate is a delegate that wraps with a device tag and can be easily
+// late bound without replicating logic everywhere
+template<typename _Signature>
+class device_delegate : public delegate<_Signature>
{
- return (this != NULL && m_owner != NULL) ? m_owner->subtag(dest, _tag) : dest.cpy(_tag);
-}
+ typedef delegate<_Signature> basetype;
+
+public:
+ // provide same set of constructors as the base class, with additional device name
+ // parameter
+ device_delegate() : basetype(), m_device_name(NULL) { }
+ device_delegate(const basetype &src) : basetype(src), m_device_name(src.m_device_name) { }
+ device_delegate(const basetype &src, delegate_late_bind &object) : basetype(src, object), m_device_name(src.m_device_name) { }
+ template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname) : basetype(funcptr, name, (_FunctionClass *)0), m_device_name(devname) { }
+ template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname, _FunctionClass *object) : basetype(funcptr, name, (_FunctionClass *)0), m_device_name(devname) { }
+ device_delegate(typename basetype::template traits<device_t>::static_func_type funcptr, const char *name) : basetype(funcptr, name, (device_t *)0), m_device_name(NULL) { }
+ device_delegate(typename basetype::template traits<device_t>::static_ref_func_type funcptr, const char *name) : basetype(funcptr, name, (device_t *)0), m_device_name(NULL) { }
+ device_delegate &operator=(const basetype &src) { *static_cast<basetype *>(this) = src; m_device_name = src.m_device_name; return *this; }
+
+ // perform the binding
+ void bind_relative_to(device_t &search_root);
+
+private:
+ // internal state
+ const char *m_device_name;
+};
+
+
+//**************************************************************************
+// INLINE FUNCTIONS
+//**************************************************************************
//-------------------------------------------------
-// first - return the first device in the list
-// with the given interface
+// subdevice - given a tag, find the device by
+// name relative to this device
//-------------------------------------------------
-template<class _InterfaceClass>
-bool device_list::first(_InterfaceClass *&intf) const
+inline device_t *device_t::subdevice(const char *tag) const
{
- for (device_t *cur = super::first(); cur != NULL; cur = cur->next())
- if (cur->interface(intf))
- return true;
- return false;
+ // safety first
+ if (this == NULL)
+ return NULL;
+
+ // empty string or NULL means this device
+ if (tag == NULL || *tag == 0)
+ return const_cast<device_t *>(this);
+
+ // do a quick lookup and return that if possible
+ device_t *quick = m_device_map.find(tag);
+ return (quick != NULL) ? quick : subdevice_slow(tag);
}
@@ -588,8 +763,9 @@ void device_delegate<_Signature>::bind_relative_to(device_t &search_root)
{
if (!basetype::isnull())
{
- device_t *device = (m_device_name == NULL) ? &search_root : search_root.subdevice(m_device_name);
- if (device == NULL) throw emu_fatalerror("Unable to locate device '%s' relative to '%s'\n", m_device_name, search_root.tag());
+ device_t *device = search_root.subdevice(m_device_name);
+ if (device == NULL)
+ throw emu_fatalerror("Unable to locate device '%s' relative to '%s'\n", m_device_name, search_root.tag());
basetype::late_bind(*device);
}
}
diff --git a/src/emu/devlegcy.c b/src/emu/devlegcy.c
index 1b15e10a2cf..185996188a8 100644
--- a/src/emu/devlegcy.c
+++ b/src/emu/devlegcy.c
@@ -200,12 +200,11 @@ void legacy_device_base::static_set_inline_float(device_t &device, UINT32 offset
// checks on a device configuration
//-------------------------------------------------
-bool legacy_device_base::device_validity_check(emu_options &options, const game_driver &driver) const
+void legacy_device_base::device_validity_check(validity_checker &valid) const
{
device_validity_check_func validity_func = reinterpret_cast<device_validity_check_func>(get_legacy_fct(DEVINFO_FCT_VALIDITY_CHECK));
if (validity_func != NULL)
- return (*validity_func)(&driver, this, options);
- return false;
+ (*validity_func)(&mconfig().gamedrv(), this, mconfig().options());
}
@@ -239,7 +238,7 @@ void legacy_device_base::device_reset()
void legacy_device_base::device_stop()
{
- if (m_started)
+ if (started())
{
device_stop_func stop_func = reinterpret_cast<device_stop_func>(get_legacy_fct(DEVINFO_FCT_STOP));
if (stop_func != NULL)
diff --git a/src/emu/devlegcy.h b/src/emu/devlegcy.h
index f598a80d2a3..b68133c5a2d 100644
--- a/src/emu/devlegcy.h
+++ b/src/emu/devlegcy.h
@@ -429,7 +429,7 @@ protected:
virtual const rom_entry *device_rom_region() const { return reinterpret_cast<const rom_entry *>(get_legacy_ptr(DEVINFO_PTR_ROM_REGION)); }
virtual machine_config_constructor device_mconfig_additions() const { return reinterpret_cast<machine_config_constructor>(get_legacy_ptr(DEVINFO_PTR_MACHINE_CONFIG)); }
virtual ioport_constructor device_input_ports() const { return reinterpret_cast<ioport_constructor>(get_legacy_ptr(DEVINFO_PTR_INPUT_PORTS)); }
- virtual bool device_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
virtual void device_stop();
diff --git a/src/emu/didisasm.h b/src/emu/didisasm.h
index f6debcb4cdf..ade6827cd72 100644
--- a/src/emu/didisasm.h
+++ b/src/emu/didisasm.h
@@ -98,5 +98,8 @@ protected:
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) = 0;
};
+// iterator
+typedef device_interface_iterator<device_disasm_interface> disasm_interface_iterator;
+
#endif /* __DIDISASM_H__ */
diff --git a/src/emu/diexec.c b/src/emu/diexec.c
index 417ed67aea4..99c43cbc389 100644
--- a/src/emu/diexec.c
+++ b/src/emu/diexec.c
@@ -484,37 +484,22 @@ void device_execute_interface::execute_set_input(int linenum, int state)
// constructed
//-------------------------------------------------
-bool device_execute_interface::interface_validity_check(emu_options &options, const game_driver &driver) const
+void device_execute_interface::interface_validity_check(validity_checker &valid) const
{
- bool error = false;
-
- /* validate the interrupts */
+ // validate the interrupts
if (m_vblank_interrupt != NULL)
{
- if (device().mconfig().devicelist().count(SCREEN) == 0)
- {
- mame_printf_error("%s: %s device '%s' has a VBLANK interrupt, but the driver is screenless!\n", driver.source_file, driver.name, device().tag());
- error = true;
- }
- else if (m_vblank_interrupt_screen != NULL && device().mconfig().devicelist().find(m_vblank_interrupt_screen) == NULL)
- {
- mame_printf_error("%s: %s device '%s' VBLANK interrupt with a non-existant screen tag (%s)!\n", driver.source_file, driver.name, device().tag(), m_vblank_interrupt_screen);
- error = true;
- }
+ screen_device_iterator iter(device().mconfig().root_device());
+ if (iter.first() == NULL)
+ mame_printf_error("VBLANK interrupt specified, but the driver is screenless\n");
+ else if (m_vblank_interrupt_screen != NULL && device().siblingdevice(m_vblank_interrupt_screen) == NULL)
+ mame_printf_error("VBLANK interrupt references a non-existant screen tag '%s'\n", m_vblank_interrupt_screen);
}
if (m_timed_interrupt != NULL && m_timed_interrupt_period == attotime::zero)
- {
- mame_printf_error("%s: %s device '%s' has a timer interrupt handler with 0 period!\n", driver.source_file, driver.name, device().tag());
- error = true;
- }
+ mame_printf_error("Timed interrupt handler specified with 0 period\n");
else if (m_timed_interrupt == NULL && m_timed_interrupt_period != attotime::zero)
- {
- mame_printf_error("%s: %s device '%s' has a no timer interrupt handler but has a non-0 period given!\n", driver.source_file, driver.name, device().tag());
- error = true;
- }
-
- return error;
+ mame_printf_error("No timer interrupt handler specified, but has a non-0 period given\n");
}
@@ -526,7 +511,8 @@ bool device_execute_interface::interface_validity_check(emu_options &options, co
void device_execute_interface::interface_pre_start()
{
// fill in the initial states
- int index = device().machine().devicelist().indexof(m_device);
+ execute_interface_iterator iter(device().machine().root_device());
+ int index = iter.indexof(*this);
m_suspend = SUSPEND_REASON_RESET;
m_profiler = profile_type(index + PROFILER_DEVICE_FIRST);
m_inttrigger = index + TRIGGER_INT;
@@ -540,13 +526,13 @@ void device_execute_interface::interface_pre_start()
m_timedint_timer = device().machine().scheduler().timer_alloc(FUNC(static_trigger_periodic_interrupt), (void *)this);
// register for save states
- m_device.save_item(NAME(m_suspend));
- m_device.save_item(NAME(m_nextsuspend));
- m_device.save_item(NAME(m_eatcycles));
- m_device.save_item(NAME(m_nexteatcycles));
- m_device.save_item(NAME(m_trigger));
- m_device.save_item(NAME(m_totalcycles));
- m_device.save_item(NAME(m_localtime));
+ device().save_item(NAME(m_suspend));
+ device().save_item(NAME(m_nextsuspend));
+ device().save_item(NAME(m_eatcycles));
+ device().save_item(NAME(m_nexteatcycles));
+ device().save_item(NAME(m_trigger));
+ device().save_item(NAME(m_totalcycles));
+ device().save_item(NAME(m_localtime));
}
@@ -627,7 +613,7 @@ void device_execute_interface::interface_post_reset()
void device_execute_interface::interface_clock_changed()
{
// recompute cps and spc
- m_cycles_per_second = clocks_to_cycles(m_device.clock());
+ m_cycles_per_second = clocks_to_cycles(device().clock());
m_attoseconds_per_cycle = HZ_TO_ATTOSECONDS(m_cycles_per_second);
// update the device's divisor
@@ -660,14 +646,14 @@ int device_execute_interface::standard_irq_callback(int irqline)
{
// get the default vector and acknowledge the interrupt if needed
int vector = m_input[irqline].default_irq_callback();
- LOG(("static_standard_irq_callback('%s', %d) $%04x\n", m_device.tag(), irqline, vector));
+ LOG(("static_standard_irq_callback('%s', %d) $%04x\n", device().tag(), irqline, vector));
// if there's a driver callback, run it to get the vector
if (m_driver_irq != NULL)
- vector = (*m_driver_irq)(&m_device, irqline);
+ vector = (*m_driver_irq)(&device(), irqline);
// notify the debugger
- debugger_interrupt_hook(&m_device, irqline);
+ debugger_interrupt_hook(&device(), irqline);
return vector;
}
@@ -682,7 +668,7 @@ attoseconds_t device_execute_interface::minimum_quantum() const
// if we don't have that information, compute it
attoseconds_t basetick = m_attoseconds_per_cycle;
if (basetick == 0)
- basetick = HZ_TO_ATTOSECONDS(clocks_to_cycles(m_device.clock()));
+ basetick = HZ_TO_ATTOSECONDS(clocks_to_cycles(device().clock()));
// apply the minimum cycle count
return basetick * min_cycles();
@@ -714,9 +700,10 @@ void device_execute_interface::on_vblank(screen_device &screen, bool vblank_stat
// generate the interrupt callback
if (!suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE))
- (*m_vblank_interrupt)(&m_device);
+ (*m_vblank_interrupt)(&device());
}
+
//-------------------------------------------------
// static_trigger_periodic_interrupt - timer
// callback for timed interrupts
@@ -731,7 +718,7 @@ void device_execute_interface::trigger_periodic_interrupt()
{
// bail if there is no routine
if (m_timed_interrupt != NULL && !suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE))
- (*m_timed_interrupt)(&m_device);
+ (*m_timed_interrupt)(&device());
}
@@ -765,7 +752,7 @@ device_execute_interface::device_input::device_input()
void device_execute_interface::device_input::start(device_execute_interface *execute, int linenum)
{
m_execute = execute;
- m_device = &m_execute->m_device;
+ m_device = &m_execute->device();
m_linenum = linenum;
reset();
diff --git a/src/emu/diexec.h b/src/emu/diexec.h
index 8a7b97c4909..59804199127 100644
--- a/src/emu/diexec.h
+++ b/src/emu/diexec.h
@@ -228,7 +228,7 @@ protected:
virtual void execute_set_input(int linenum, int state);
// interface-level overrides
- virtual bool interface_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void interface_validity_check(validity_checker &valid) const;
virtual void interface_pre_start();
virtual void interface_post_start();
virtual void interface_pre_reset();
@@ -322,6 +322,9 @@ private:
attoseconds_t minimum_quantum() const;
};
+// iterator
+typedef device_interface_iterator<device_execute_interface> execute_interface_iterator;
+
//**************************************************************************
diff --git a/src/emu/diimage.c b/src/emu/diimage.c
index f23c4823599..9ceefc34c38 100644
--- a/src/emu/diimage.c
+++ b/src/emu/diimage.c
@@ -1067,17 +1067,9 @@ void device_image_interface::unload()
void device_image_interface::update_names()
{
- const device_image_interface *image = NULL;
- int count = 0;
- int index = -1;
-
- for (bool gotone = device().mconfig().devicelist().first(image); gotone; gotone = image->next(image))
- {
- if (this == image)
- index = count;
- if (image->image_type() == image_type())
- count++;
- }
+ image_interface_iterator iter(device().mconfig().root_device());
+ int count = iter.count();
+ int index = iter.indexof(*this);
if (count > 1) {
m_instance_name.printf("%s%d", device_typename(image_type()), index + 1);
m_brief_instance_name.printf("%s%d", device_brieftypename(image_type()), index + 1);
@@ -1103,7 +1095,7 @@ ui_menu_control_device_image::ui_menu_control_device_image(running_machine &mach
{
image = _image;
- slc = 0;
+ sld = 0;
swi = image->software_entry();
swp = image->part_entry();
@@ -1220,8 +1212,8 @@ void ui_menu_control_device_image::handle()
}
case START_SOFTLIST:
- slc = 0;
- ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software(machine(), container, image->image_interface(), &slc)));
+ sld = 0;
+ ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software(machine(), container, image->image_interface(), &sld)));
state = SELECT_SOFTLIST;
break;
@@ -1233,17 +1225,17 @@ void ui_menu_control_device_image::handle()
}
case SELECT_SOFTLIST:
- if(!slc) {
+ if(!sld) {
ui_menu::stack_pop(machine());
break;
}
software_info_name = "";
- ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software_list(machine(), container, slc, image->image_interface(), software_info_name)));
+ ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software_list(machine(), container, sld, image->image_interface(), software_info_name)));
state = SELECT_PARTLIST;
break;
case SELECT_PARTLIST:
- swl = software_list_open(machine().options(), slc->list_name, false, NULL);
+ swl = software_list_open(machine().options(), sld->list_name(), false, NULL);
swi = software_list_find(swl, software_info_name, NULL);
if(swinfo_has_multiple_parts(swi, image->image_interface())) {
submenu_result = -1;
diff --git a/src/emu/diimage.h b/src/emu/diimage.h
index 583b058f607..84fafc69952 100644
--- a/src/emu/diimage.h
+++ b/src/emu/diimage.h
@@ -324,6 +324,9 @@ protected:
bool m_is_loading;
};
+// iterator
+typedef device_interface_iterator<device_image_interface> image_interface_iterator;
+
class ui_menu_control_device_image : public ui_menu {
public:
ui_menu_control_device_image(running_machine &machine, render_container *container, device_image_interface *image);
@@ -344,10 +347,10 @@ protected:
int submenu_result;
bool create_confirmed;
bool softlist_done;
- const class software_list *swl;
- const class software_info *swi;
- const class software_part *swp;
- const class software_list_config *slc;
+ const struct software_list *swl;
+ const software_info *swi;
+ const software_part *swp;
+ const class software_list_device *sld;
astring software_info_name;
void test_create(bool &can_create, bool &need_confirm);
diff --git a/src/emu/dimemory.c b/src/emu/dimemory.c
index bf9a5b2cfb7..0a806d82341 100644
--- a/src/emu/dimemory.c
+++ b/src/emu/dimemory.c
@@ -227,10 +227,9 @@ bool device_memory_interface::memory_readop(offs_t offset, int size, UINT64 &val
// checks on the memory configuration
//-------------------------------------------------
-bool device_memory_interface::interface_validity_check(emu_options &options, const game_driver &driver) const
+void device_memory_interface::interface_validity_check(validity_checker &valid) const
{
bool detected_overlap = DETECT_OVERLAPPING_MEMORY ? false : true;
- bool error = false;
// loop over all address spaces
for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++)
@@ -253,15 +252,9 @@ bool device_memory_interface::interface_validity_check(emu_options &options, con
// validate the global map parameters
if (map->m_spacenum != spacenum)
- {
- mame_printf_error("%s: %s device '%s' space %d has address space %d handlers!\n", driver.source_file, driver.name, device().tag(), spacenum, map->m_spacenum);
- error = true;
- }
+ mame_printf_error("Space %d has address space %d handlers!\n", spacenum, map->m_spacenum);
if (map->m_databits != datawidth)
- {
- mame_printf_error("%s: %s device '%s' uses wrong memory handlers for %s space! (width = %d, memory = %08x)\n", driver.source_file, driver.name, device().tag(), spaceconfig->m_name, datawidth, map->m_databits);
- error = true;
- }
+ mame_printf_error("Wrong memory handlers provided for %s space! (width = %d, memory = %08x)\n", spaceconfig->m_name, datawidth, map->m_databits);
// loop over entries and look for errors
for (address_map_entry *entry = map->m_entrylist.first(); entry != NULL; entry = entry->next())
@@ -278,7 +271,7 @@ bool device_memory_interface::interface_validity_check(emu_options &options, con
((entry->m_read.m_type != AMH_NONE && scan->m_read.m_type != AMH_NONE) ||
(entry->m_write.m_type != AMH_NONE && scan->m_write.m_type != AMH_NONE)))
{
- mame_printf_warning("%s: %s '%s' %s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", driver.source_file, driver.name, device().tag(), spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_read.m_type, entry->m_write.m_type, scan->m_addrstart, scan->m_addrend, scan->m_read.m_type, scan->m_write.m_type);
+ mame_printf_warning("%s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_read.m_type, entry->m_write.m_type, scan->m_addrstart, scan->m_addrend, scan->m_read.m_type, scan->m_write.m_type);
detected_overlap = true;
break;
}
@@ -286,17 +279,11 @@ bool device_memory_interface::interface_validity_check(emu_options &options, con
// look for inverted start/end pairs
if (byteend < bytestart)
- {
- mame_printf_error("%s: %s wrong %s memory read handler start = %08x > end = %08x\n", driver.source_file, driver.name, spaceconfig->m_name, entry->m_addrstart, entry->m_addrend);
- error = true;
- }
+ mame_printf_error("Wrong %s memory read handler start = %08x > end = %08x\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend);
// look for misaligned entries
if ((bytestart & (alignunit - 1)) != 0 || (byteend & (alignunit - 1)) != (alignunit - 1))
- {
- mame_printf_error("%s: %s wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", driver.source_file, driver.name, spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, alignunit);
- error = true;
- }
+ mame_printf_error("Wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, alignunit);
// if this is a program space, auto-assign implicit ROM entries
if (entry->m_read.m_type == AMH_ROM && entry->m_region == NULL)
@@ -308,81 +295,54 @@ bool device_memory_interface::interface_validity_check(emu_options &options, con
// if this entry references a memory region, validate it
if (entry->m_region != NULL && entry->m_share == 0)
{
- // look for the region
+ // make sure we can resolve the full path to the region
bool found = false;
+ astring entry_region;
+ device().siblingtag(entry_region, entry->m_region);
+
+ // look for the region
for (const rom_source *source = rom_first_source(device().mconfig()); source != NULL && !found; source = rom_next_source(*source))
- for (const rom_entry *romp = rom_first_region(*source); !ROMENTRY_ISEND(romp) && !found; romp++)
+ for (const rom_entry *romp = rom_first_region(*source); romp != NULL && !found; romp = rom_next_region(romp))
{
- const char *regiontag_c = ROMREGION_GETTAG(romp);
- if (regiontag_c != NULL)
+ astring fulltag;
+ rom_region_name(fulltag, &device().mconfig().gamedrv(), source, romp);
+ if (fulltag == entry_region)
{
- astring fulltag;
- astring regiontag;
-
- // a leading : on a region name indicates an absolute region, so fix up accordingly
- if (entry->m_region[0] == ':')
- {
- regiontag = &entry->m_region[1];
- }
- else
- {
- if (strchr(entry->m_region,':')) {
- regiontag = entry->m_region;
- } else {
- device().siblingtag(regiontag, entry->m_region);
- }
- }
- rom_region_name(fulltag, &driver, source, romp);
- if (fulltag.cmp(regiontag) == 0)
- {
- // verify the address range is within the region's bounds
- offs_t length = ROMREGION_GETLENGTH(romp);
- if (entry->m_rgnoffs + (byteend - bytestart + 1) > length)
- {
- mame_printf_error("%s: %s device '%s' %s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", driver.source_file, driver.name, device().tag(), spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, length);
- error = true;
- }
- found = true;
- }
+ // verify the address range is within the region's bounds
+ offs_t length = ROMREGION_GETLENGTH(romp);
+ if (entry->m_rgnoffs + (byteend - bytestart + 1) > length)
+ mame_printf_error("%s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, length);
+ found = true;
}
}
// error if not found
if (!found)
- {
- mame_printf_error("%s: %s device '%s' %s space memory map entry %X-%X references non-existant region '%s'\n", driver.source_file, driver.name, device().tag(), spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region);
- error = true;
- }
+ mame_printf_error("%s space memory map entry %X-%X references non-existant region '%s'\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region);
}
// make sure all devices exist
- if ((entry->m_read.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_read.m_tag != NULL && device().mconfig().devicelist().find(entry->m_read.m_tag) == NULL) ||
- (entry->m_write.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_write.m_tag != NULL && device().mconfig().devicelist().find(entry->m_write.m_tag) == NULL))
- {
- mame_printf_error("%s: %s device '%s' %s space memory map entry references nonexistant device '%s'\n", driver.source_file, driver.name, device().tag(), spaceconfig->m_name, entry->m_write.m_tag);
- error = true;
- }
+ if (entry->m_read.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_read.m_tag && device().siblingdevice(entry->m_read.m_tag) == NULL)
+ mame_printf_error("%s space memory map entry references nonexistant device '%s'\n", spaceconfig->m_name, entry->m_read.m_tag.cstr());
+ if (entry->m_write.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_write.m_tag && device().siblingdevice(entry->m_write.m_tag) == NULL)
+ mame_printf_error("%s space memory map entry references nonexistant device '%s'\n", spaceconfig->m_name, entry->m_write.m_tag.cstr());
// make sure ports exist
// if ((entry->m_read.m_type == AMH_PORT && entry->m_read.m_tag != NULL && portlist.find(entry->m_read.m_tag) == NULL) ||
// (entry->m_write.m_type == AMH_PORT && entry->m_write.m_tag != NULL && portlist.find(entry->m_write.m_tag) == NULL))
-// {
-// mame_printf_error("%s: %s device '%s' %s space memory map entry references nonexistant port tag '%s'\n", driver.source_file, driver.name, device().tag(), spaceconfig->m_name, entry->m_read.tag);
-// error = true;
-// }
+// mame_printf_error("%s space memory map entry references nonexistant port tag '%s'\n", spaceconfig->m_name, entry->m_read.m_tag.cstr());
// validate bank and share tags
- if (entry->m_read.m_type == AMH_BANK && !validate_tag(driver, "bank", entry->m_read.m_tag))
- error = true ;
- if (entry->m_write.m_type == AMH_BANK && !validate_tag(driver, "bank", entry->m_write.m_tag))
- error = true;
- if (entry->m_share != NULL && !validate_tag(driver, "share", entry->m_share))
- error = true;
+ if (entry->m_read.m_type == AMH_BANK)
+ valid.validate_tag(entry->m_read.m_tag);
+ if (entry->m_write.m_type == AMH_BANK)
+ valid.validate_tag(entry->m_write.m_tag);
+ if (entry->m_share != NULL)
+ valid.validate_tag(entry->m_share);
}
// release the address map
global_free(map);
}
}
- return error;
}
diff --git a/src/emu/dimemory.h b/src/emu/dimemory.h
index b0e2da346bb..c6efce57ebe 100644
--- a/src/emu/dimemory.h
+++ b/src/emu/dimemory.h
@@ -134,13 +134,16 @@ protected:
virtual bool memory_readop(offs_t offset, int size, UINT64 &value);
// interface-level overrides
- virtual bool interface_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void interface_validity_check(validity_checker &valid) const;
// configuration
address_map_constructor m_address_map[ADDRESS_SPACES]; // address maps for each address space
address_space * m_addrspace[ADDRESS_SPACES]; // reported address spaces
};
+// iterator
+typedef device_interface_iterator<device_memory_interface> memory_interface_iterator;
+
//**************************************************************************
diff --git a/src/emu/dinetwork.h b/src/emu/dinetwork.h
index 592853af78a..bc1546e17c4 100644
--- a/src/emu/dinetwork.h
+++ b/src/emu/dinetwork.h
@@ -28,4 +28,9 @@ protected:
class netdev *m_dev;
int m_intf;
};
+
+
+// iterator
+typedef device_interface_iterator<device_network_interface> network_interface_iterator;
+
#endif
diff --git a/src/emu/dinvram.h b/src/emu/dinvram.h
index 30b490c60a1..ad9947ea1cc 100644
--- a/src/emu/dinvram.h
+++ b/src/emu/dinvram.h
@@ -74,5 +74,8 @@ protected:
virtual void nvram_write(emu_file &file) = 0;
};
+// iterator
+typedef device_interface_iterator<device_nvram_interface> nvram_interface_iterator;
+
#endif /* __DINVRAM_H__ */
diff --git a/src/emu/dislot.h b/src/emu/dislot.h
index 630a76b677e..bdc7413dc92 100644
--- a/src/emu/dislot.h
+++ b/src/emu/dislot.h
@@ -48,8 +48,8 @@ public:
static void static_set_slot_info(device_t &device, const slot_interface *slots_info, const char *default_card,const input_device_default *default_input);
const slot_interface* get_slot_interfaces() const { return m_slot_interfaces; };
- const char * get_default_card(const device_list &devlist, emu_options &options) const { return m_default_card; };
- virtual const char * get_default_card_software(const device_list &devlist, emu_options &options) const { return NULL; };
+ const char * get_default_card(const machine_config &config, emu_options &options) const { return m_default_card; };
+ virtual const char * get_default_card_software(const machine_config &config, emu_options &options) const { return NULL; };
const input_device_default *input_ports_defaults() const { return m_input_defaults; }
device_t* get_card_device();
protected:
@@ -58,6 +58,9 @@ protected:
const slot_interface *m_slot_interfaces;
};
+// iterator
+typedef device_interface_iterator<device_slot_interface> slot_interface_iterator;
+
// ======================> device_slot_card_interface
class device_slot_card_interface : public device_interface
diff --git a/src/emu/disound.c b/src/emu/disound.c
index cb004c28fa2..2889d58f852 100644
--- a/src/emu/disound.c
+++ b/src/emu/disound.c
@@ -232,30 +232,21 @@ void device_sound_interface::set_output_gain(int outputnum, float gain)
// constructed
//-------------------------------------------------
-bool device_sound_interface::interface_validity_check(emu_options &options, const game_driver &driver) const
+void device_sound_interface::interface_validity_check(validity_checker &valid) const
{
- bool error = false;
-
// loop over all the routes
for (const sound_route *route = first_route(); route != NULL; route = route->next())
{
// find a device with the requested tag
- const device_t *target = device().mconfig().devicelist().find(route->m_target.cstr());
+ const device_t *target = device().siblingdevice(route->m_target.cstr());
if (target == NULL)
- {
- mame_printf_error("%s: %s attempting to route sound to non-existant device '%s'\n", driver.source_file, driver.name, route->m_target.cstr());
- error = true;
- }
+ mame_printf_error("Attempting to route sound to non-existant device '%s'\n", route->m_target.cstr());
// if it's not a speaker or a sound device, error
const device_sound_interface *sound;
if (target != NULL && target->type() != SPEAKER && !target->interface(sound))
- {
- mame_printf_error("%s: %s attempting to route sound to a non-sound device '%s' (%s)\n", driver.source_file, driver.name, route->m_target.cstr(), target->name());
- error = true;
- }
+ mame_printf_error("Attempting to route sound to a non-sound device '%s' (%s)\n", route->m_target.cstr(), target->name());
}
- return error;
}
@@ -267,8 +258,8 @@ bool device_sound_interface::interface_validity_check(emu_options &options, cons
void device_sound_interface::interface_pre_start()
{
// scan all the sound devices
- device_sound_interface *sound = NULL;
- for (bool gotone = m_device.machine().devicelist().first(sound); gotone; gotone = sound->next(sound))
+ sound_interface_iterator iter(m_device.machine().root_device());
+ for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next())
{
// scan each route on the device
for (const sound_route *route = sound->first_route(); route != NULL; route = route->next())
@@ -282,7 +273,7 @@ void device_sound_interface::interface_pre_start()
// now iterate through devices again and assign any auto-allocated inputs
m_auto_allocated_inputs = 0;
- for (bool gotone = m_device.machine().devicelist().first(sound); gotone; gotone = sound->next(sound))
+ for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next())
{
// scan each route on the device
for (const sound_route *route = sound->first_route(); route != NULL; route = route->next())
@@ -307,8 +298,8 @@ void device_sound_interface::interface_pre_start()
void device_sound_interface::interface_post_start()
{
// iterate over all the sound devices
- device_sound_interface *sound = NULL;
- for (bool gotone = m_device.machine().devicelist().first(sound); gotone; gotone = sound->next(sound))
+ sound_interface_iterator iter(m_device.machine().root_device());
+ for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next())
{
// scan each route on the device
for (const sound_route *route = sound->first_route(); route != NULL; route = route->next())
diff --git a/src/emu/disound.h b/src/emu/disound.h
index c4c9a2f13c0..c94187337c4 100644
--- a/src/emu/disound.h
+++ b/src/emu/disound.h
@@ -138,7 +138,7 @@ public:
protected:
// optional operation overrides
- virtual bool interface_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void interface_validity_check(validity_checker &valid) const;
virtual void interface_pre_start();
virtual void interface_post_start();
virtual void interface_pre_reset();
@@ -149,5 +149,7 @@ protected:
int m_auto_allocated_inputs; // number of auto-allocated inputs targeting us
};
+// iterator
+typedef device_interface_iterator<device_sound_interface> sound_interface_iterator;
#endif /* __DISOUND_H__ */
diff --git a/src/emu/distate.c b/src/emu/distate.c
index 2a18ea59c9d..6a0621d3eac 100644
--- a/src/emu/distate.c
+++ b/src/emu/distate.c
@@ -517,7 +517,7 @@ device_state_entry &device_state_interface::state_add(int index, const char *sym
assert(symbol != NULL);
// allocate new entry
- device_state_entry *entry = auto_alloc(device().machine(), device_state_entry(index, symbol, data, size));
+ device_state_entry *entry = global_alloc(device_state_entry(index, symbol, data, size));
// append to the end of the list
m_state_list.append(*entry);
diff --git a/src/emu/distate.h b/src/emu/distate.h
index b38f692fc7e..66b756e566b 100644
--- a/src/emu/distate.h
+++ b/src/emu/distate.h
@@ -195,6 +195,9 @@ protected:
// fast access to common entries
};
+// iterator
+typedef device_interface_iterator<device_state_interface> state_interface_iterator;
+
//**************************************************************************
diff --git a/src/emu/emuopts.c b/src/emu/emuopts.c
index 7d7196fbfc0..cc06c91c98f 100644
--- a/src/emu/emuopts.c
+++ b/src/emu/emuopts.c
@@ -226,11 +226,11 @@ bool emu_options::add_slot_options(bool isfirst)
// iterate through all slot devices
options_entry entry[2] = { { 0 }, { 0 } };
bool first = true;
- const device_slot_interface *slot = NULL;
// create the configuration
machine_config config(*cursystem, *this);
bool added = false;
- for (bool gotone = config.devicelist().first(slot); gotone; gotone = slot->next(slot))
+ slot_interface_iterator iter(config.root_device());
+ for (const device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next())
{
// first device? add the header as to be pretty
if (first && isfirst)
@@ -253,7 +253,7 @@ bool emu_options::add_slot_options(bool isfirst)
entry[0].name = slot->device().tag();
entry[0].description = NULL;
entry[0].flags = OPTION_STRING | OPTION_FLAG_DEVICE;
- entry[0].defvalue = (slot->get_slot_interfaces() != NULL) ? slot->get_default_card(config.devicelist(),*this) : NULL;
+ entry[0].defvalue = (slot->get_slot_interfaces() != NULL) ? slot->get_default_card(config,*this) : NULL;
add_entries(entry, true);
added = true;
@@ -275,10 +275,10 @@ void emu_options::update_slot_options()
return;
// iterate through all slot devices
- const device_slot_interface *slot = NULL;
// create the configuration
machine_config config(*cursystem, *this);
- for (bool gotone = config.devicelist().first(slot); gotone; gotone = slot->next(slot))
+ slot_interface_iterator iter(config.root_device());
+ for (const device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next())
{
// retrieve info about the device instance
astring option_name;
@@ -286,7 +286,7 @@ void emu_options::update_slot_options()
if (exists(slot->device().tag())) {
if (slot->get_slot_interfaces() != NULL) {
- const char *def = slot->get_default_card_software(config.devicelist(),*this);
+ const char *def = slot->get_default_card_software(config,*this);
if (def) set_default_value(slot->device().tag(),def);
}
}
@@ -308,9 +308,9 @@ void emu_options::add_device_options(bool isfirst)
options_entry entry[2] = { { 0 }, { 0 } };
bool first = true;
// iterate through all image devices
- const device_image_interface *image = NULL;
machine_config config(*cursystem, *this);
- for (bool gotone = config.devicelist().first(image); gotone; gotone = image->next(image))
+ image_interface_iterator iter(config.root_device());
+ for (const device_image_interface *image = iter.first(); image != NULL; image = iter.next())
{
// first device? add the header as to be pretty
if (first && isfirst)
@@ -438,7 +438,8 @@ void emu_options::parse_standard_inis(astring &error_string)
// parse "vector.ini" for vector games
{
machine_config config(*cursystem, *this);
- for (const screen_device *device = config.first_screen(); device != NULL; device = device->next_screen())
+ screen_device_iterator iter(config.root_device());
+ for (const screen_device *device = iter.first(); device != NULL; device = iter.next())
if (device->screen_type() == SCREEN_TYPE_VECTOR)
{
parse_one_ini("vector", OPTION_PRIORITY_VECTOR_INI, &error_string);
diff --git a/src/emu/image.c b/src/emu/image.c
index fc8776fa218..260bef069c9 100644
--- a/src/emu/image.c
+++ b/src/emu/image.c
@@ -68,7 +68,6 @@ static void image_dirs_load(running_machine &machine, int config_type, xml_data_
xml_data_node *node;
const char *dev_instance;
const char *working_directory;
- device_image_interface *image = NULL;
if ((config_type == CONFIG_TYPE_GAME) && (parentnode != NULL))
{
@@ -78,7 +77,8 @@ static void image_dirs_load(running_machine &machine, int config_type, xml_data_
if ((dev_instance != NULL) && (dev_instance[0] != '\0'))
{
- for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image))
+ image_interface_iterator iter(machine.root_device());
+ for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
{
if (!strcmp(dev_instance, image->instance_name())) {
working_directory = xml_get_attribute_string(node, "directory", NULL);
@@ -102,12 +102,12 @@ static void image_dirs_save(running_machine &machine, int config_type, xml_data_
{
xml_data_node *node;
const char *dev_instance;
- device_image_interface *image = NULL;
/* only care about game-specific data */
if (config_type == CONFIG_TYPE_GAME)
{
- for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image))
+ image_interface_iterator iter(machine.root_device());
+ for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
{
dev_instance = image->instance_name();
@@ -160,9 +160,9 @@ static void image_options_extract(running_machine &machine)
no need to assert in case they are missing */
{
int index = 0;
- device_image_interface *image = NULL;
- for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image))
+ image_interface_iterator iter(machine.root_device());
+ for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
{
const char *filename = image->filename();
@@ -186,12 +186,11 @@ static void image_options_extract(running_machine &machine)
void image_unload_all(running_machine &machine)
{
- device_image_interface *image = NULL;
-
// extract the options
image_options_extract(machine);
- for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image))
+ image_interface_iterator iter(machine.root_device());
+ for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
{
// unload this image
image->unload();
@@ -205,10 +204,10 @@ void image_unload_all(running_machine &machine)
void image_device_init(running_machine &machine)
{
const char *image_name;
- device_image_interface *image = NULL;
/* make sure that any required devices have been allocated */
- for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image))
+ image_interface_iterator iter(machine.root_device());
+ for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
{
/* is an image specified for this image */
image_name = machine.options().device_option(*image);
@@ -239,7 +238,7 @@ void image_device_init(running_machine &machine)
}
}
- for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image))
+ for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
{
/* is an image specified for this image */
image_name = image->filename();
@@ -264,10 +263,9 @@ void image_device_init(running_machine &machine)
void image_postdevice_init(running_machine &machine)
{
- device_image_interface *image = NULL;
-
/* make sure that any required devices have been allocated */
- for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image))
+ image_interface_iterator iter(machine.root_device());
+ for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
{
int result = image->finish_load();
/* did the image load fail? */
@@ -373,8 +371,6 @@ static char *strip_extension(const char *filename)
astring &image_info_astring(running_machine &machine, astring &string)
{
- device_image_interface *image = NULL;
-
string.printf("%s\n\n", machine.system().description);
#if 0
@@ -385,7 +381,8 @@ astring &image_info_astring(running_machine &machine, astring &string)
}
#endif
- for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image))
+ image_interface_iterator iter(machine.root_device());
+ for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
{
const char *name = image->filename();
if (name != NULL)
@@ -480,15 +477,8 @@ void image_battery_save_by_name(emu_options &options, const char *filename, cons
-------------------------------------------------*/
device_image_interface *image_from_absolute_index(running_machine &machine, int absolute_index)
{
- device_image_interface *image = NULL;
- int cnt = 0;
- /* make sure that any required devices have been allocated */
- for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image))
- {
- if (cnt==absolute_index) return image;
- cnt++;
- }
- return NULL;
+ image_interface_iterator iter(machine.root_device());
+ return iter.byindex(absolute_index);
}
/*-------------------------------------------------
diff --git a/src/emu/imagedev/bitbngr.h b/src/emu/imagedev/bitbngr.h
index 25a25915537..a6f887201ae 100644
--- a/src/emu/imagedev/bitbngr.h
+++ b/src/emu/imagedev/bitbngr.h
@@ -163,4 +163,7 @@ private:
// device type definition
extern const device_type BITBANGER;
+// device iterator
+typedef device_type_iterator<&device_creator<bitbanger_device>, bitbanger_device> bitbanger_device_iterator;
+
#endif /* __BITBNGR_H__ */
diff --git a/src/emu/imagedev/cassette.c b/src/emu/imagedev/cassette.c
index 474256d5ec5..dd2408f729d 100644
--- a/src/emu/imagedev/cassette.c
+++ b/src/emu/imagedev/cassette.c
@@ -336,7 +336,7 @@ void cassette_image_device::call_display()
int n;
double position, length;
cassette_state uistate;
- device_t *dev;
+ cassette_image_device *dev;
static const UINT8 shapes[8] = { 0x2d, 0x5c, 0x7c, 0x2f, 0x2d, 0x20, 0x20, 0x20 };
/* abort if we should not be showing the image */
@@ -354,13 +354,9 @@ void cassette_image_device::call_display()
x = 0.2f;
y = 0.5f;
- dev = device().machine().devicelist().first(CASSETTE );
-
- while ( dev && strcmp( dev->tag(), device().tag() ) )
- {
+ cassette_device_iterator iter(device().machine().root_device());
+ for (dev = iter.first(); dev != NULL && strcmp( dev->tag(), device().tag() ); dev = iter.next())
y += 1;
- dev = dev->typenext();
- }
y *= ui_get_line_height(device().machine()) + 2.0f * UI_BOX_TB_BORDER;
/* choose which frame of the animation we are at */
diff --git a/src/emu/imagedev/cassette.h b/src/emu/imagedev/cassette.h
index c7476e169a0..cec381c2e0f 100644
--- a/src/emu/imagedev/cassette.h
+++ b/src/emu/imagedev/cassette.h
@@ -113,6 +113,9 @@ private:
// device type definition
extern const device_type CASSETTE;
+// device iterator
+typedef device_type_iterator<&device_creator<cassette_image_device>, cassette_image_device> cassette_device_iterator;
+
/***************************************************************************
DEVICE CONFIGURATION MACROS
***************************************************************************/
diff --git a/src/emu/info.c b/src/emu/info.c
index e9f15949c33..2ce0ad90692 100644
--- a/src/emu/info.c
+++ b/src/emu/info.c
@@ -266,13 +266,13 @@ void info_xml_creator::output_devices()
m_drivlist.reset();
m_drivlist.next();
machine_config &config = m_drivlist.config();
- device_t *owner = config.devicelist().first();
+ device_t &owner = config.root_device();
// check if all are listed, note that empty one is included
bool display_all = driver_list::total() == (m_drivlist.count()+1);
for(int i=0;i<m_device_count;i++) {
if (display_all || (m_device_used[i]!=0)) {
device_type type = *s_devices_sorted[i];
- device_t *dev = (*type)(config, "dummy", owner, 0);
+ device_t *dev = (*type)(config, "dummy", &owner, 0);
dev->config_complete();
// print the header and the game name
@@ -311,7 +311,8 @@ void info_xml_creator::output_one()
machine_config &config = m_drivlist.config();
ioport_list portlist;
astring errors;
- for (device_t *device = config.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(config.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
input_port_list_init(*device, portlist, errors);
// print the header and the game name
@@ -407,7 +408,8 @@ void info_xml_creator::output_device_roms()
void info_xml_creator::output_sampleof()
{
// iterate over sample devices
- for (const device_t *device = m_drivlist.config().devicelist().first(SAMPLES); device != NULL; device = device->typenext())
+ samples_device_iterator iter(m_drivlist.config().root_device());
+ for (samples_device *device = iter.first(); device != NULL; device = iter.next())
{
const char *const *samplenames = ((const samples_interface *)device->static_config())->samplenames;
if (samplenames != NULL)
@@ -566,7 +568,8 @@ void info_xml_creator::output_rom(const rom_source *source)
void info_xml_creator::output_sample()
{
// iterate over sample devices
- for (const device_t *device = m_drivlist.config().devicelist().first(SAMPLES); device != NULL; device = device->typenext())
+ samples_device_iterator iter(m_drivlist.config().root_device());
+ for (const device_t *device = iter.first(); device != NULL; device = iter.next())
{
const char *const *samplenames = ((const samples_interface *)device->static_config())->samplenames;
if (samplenames != NULL)
@@ -602,8 +605,8 @@ void info_xml_creator::output_sample()
void info_xml_creator::output_chips()
{
// iterate over executable devices
- device_execute_interface *exec = NULL;
- for (bool gotone = m_drivlist.config().devicelist().first(exec); gotone; gotone = exec->next(exec))
+ execute_interface_iterator execiter(m_drivlist.config().root_device());
+ for (device_execute_interface *exec = execiter.first(); exec != NULL; exec = execiter.next())
{
fprintf(m_output, "\t\t<chip");
fprintf(m_output, " type=\"cpu\"");
@@ -614,8 +617,8 @@ void info_xml_creator::output_chips()
}
// iterate over sound devices
- device_sound_interface *sound = NULL;
- for (bool gotone = m_drivlist.config().devicelist().first(sound); gotone; gotone = sound->next(sound))
+ sound_interface_iterator sounditer(m_drivlist.config().root_device());
+ for (device_sound_interface *sound = sounditer.first(); sound != NULL; sound = sounditer.next())
{
fprintf(m_output, "\t\t<chip");
fprintf(m_output, " type=\"audio\"");
@@ -636,7 +639,8 @@ void info_xml_creator::output_chips()
void info_xml_creator::output_display()
{
// iterate over screens
- for (const screen_device *device = m_drivlist.config().first_screen(); device != NULL; device = device->next_screen())
+ screen_device_iterator iter(m_drivlist.config().root_device());
+ for (const screen_device *device = iter.first(); device != NULL; device = iter.next())
{
fprintf(m_output, "\t\t<display");
@@ -714,11 +718,12 @@ void info_xml_creator::output_display()
void info_xml_creator::output_sound()
{
- int speakers = m_drivlist.config().devicelist().count(SPEAKER);
+ speaker_device_iterator spkiter(m_drivlist.config().root_device());
+ int speakers = spkiter.count();
// if we have no sound, zero m_output the speaker count
- const device_sound_interface *sound = NULL;
- if (!m_drivlist.config().devicelist().first(sound))
+ sound_interface_iterator snditer(m_drivlist.config().root_device());
+ if (snditer.first() == NULL)
speakers = 0;
fprintf(m_output, "\t\t<sound channels=\"%d\"/>\n", speakers);
@@ -1144,8 +1149,8 @@ void info_xml_creator::output_driver()
void info_xml_creator::output_images()
{
- const device_image_interface *dev = NULL;
- for (bool gotone = m_drivlist.config().devicelist().first(dev); gotone; gotone = dev->next(dev))
+ image_interface_iterator iter(m_drivlist.config().root_device());
+ for (const device_image_interface *dev = iter.first(); dev != NULL; dev = iter.next())
{
// print m_output device type
fprintf(m_output, "\t\t<device type=\"%s\"", xml_normalize_string(dev->image_type_name()));
@@ -1194,8 +1199,8 @@ void info_xml_creator::output_images()
void info_xml_creator::output_slots()
{
- const device_slot_interface *slot = NULL;
- for (bool gotone = m_drivlist.config().devicelist().first(slot); gotone; gotone = slot->next(slot))
+ slot_interface_iterator iter(m_drivlist.config().root_device());
+ for (const device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next())
{
// print m_output device type
fprintf(m_output, "\t\t<slot name=\"%s\">\n", xml_normalize_string(slot->device().tag()));
@@ -1210,9 +1215,9 @@ void info_xml_creator::output_slots()
{
fprintf(m_output, "\t\t\t<slotoption");
fprintf(m_output, " name=\"%s\"", xml_normalize_string(intf[i].name));
- if (slot->get_default_card(m_drivlist.config().devicelist(), m_drivlist.options()))
+ if (slot->get_default_card(m_drivlist.config(), m_drivlist.options()))
{
- if (slot->get_default_card(m_drivlist.config().devicelist(), m_drivlist.options()) == intf[i].name)
+ if (slot->get_default_card(m_drivlist.config(), m_drivlist.options()) == intf[i].name)
fprintf(m_output, " default=\"yes\"");
}
fprintf(m_output, "/>\n");
@@ -1230,13 +1235,13 @@ void info_xml_creator::output_slots()
void info_xml_creator::output_software_list()
{
- for (const device_t *dev = m_drivlist.config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext())
+ software_list_device_iterator iter(m_drivlist.config().root_device());
+ for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next())
{
- software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config();
- fprintf(m_output, "\t\t<softwarelist name=\"%s\" ", swlist->list_name);
- fprintf(m_output, "status=\"%s\" ", (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) ? "original" : "compatible");
- if (swlist->filter) {
- fprintf(m_output, "filter=\"%s\" ", swlist->filter);
+ fprintf(m_output, "\t\t<softwarelist name=\"%s\" ", swlist->list_name());
+ fprintf(m_output, "status=\"%s\" ", (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) ? "original" : "compatible");
+ if (swlist->filter()) {
+ fprintf(m_output, "filter=\"%s\" ", swlist->filter());
}
fprintf(m_output, "/>\n");
}
@@ -1251,10 +1256,9 @@ void info_xml_creator::output_software_list()
void info_xml_creator::output_ramoptions()
{
- for (const device_t *device = m_drivlist.config().devicelist().first(RAM); device != NULL; device = device->typenext())
+ ram_device_iterator iter(m_drivlist.config().root_device());
+ for (const ram_device *ram = iter.first(); ram != NULL; ram = iter.next())
{
- const ram_device *ram = downcast<const ram_device *>(device);
-
fprintf(m_output, "\t\t<ramoption default=\"1\">%u</ramoption>\n", ram->default_size());
if (ram->extra_options() != NULL)
diff --git a/src/emu/ioport.c b/src/emu/ioport.c
index 5215b7735f3..7f93baa417c 100644
--- a/src/emu/ioport.c
+++ b/src/emu/ioport.c
@@ -903,7 +903,8 @@ time_t input_port_init(running_machine &machine)
init_port_types(machine);
/* if we have a token list, proceed */
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(machine.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
{
astring errors;
input_port_list_init(*device, machine.m_portlist, errors);
@@ -1500,10 +1501,10 @@ input_port_value input_port_read(running_machine &machine, const char *tag)
a device input port specified by tag
-------------------------------------------------*/
-input_port_value input_port_read(device_t *device, const char *tag)
+input_port_value input_port_read(device_t &device, const char *tag)
{
- astring tempstring;
- const input_port_config *port = device->machine().port(device->subtag(tempstring, tag));
+ astring fullpath;
+ const input_port_config *port = device.machine().port(device.subtag(fullpath, tag));
if (port == NULL)
fatalerror("Unable to locate input port '%s'", tag);
return input_port_read_direct(port);
@@ -1721,7 +1722,7 @@ void input_port_write_safe(running_machine &machine, const char *tag, input_port
if the given condition attached is true
-------------------------------------------------*/
-int input_condition_true(running_machine &machine, const input_condition *condition,device_t &owner)
+int input_condition_true(running_machine &machine, const input_condition *condition, device_t &owner)
{
input_port_value condvalue;
@@ -1939,20 +1940,6 @@ static astring &get_keyboard_key_name(astring &name, const input_field_config *f
states based on the tokens
-------------------------------------------------*/
-inline const char *get_device_tag(const device_t &device, const char *tag, astring &finaltag)
-{
- if (strcmp(tag, DEVICE_SELF) == 0)
- finaltag.cpy(device.tag());
- else if (strcmp(tag, DEVICE_SELF_OWNER) == 0)
- {
- assert(device.owner() != NULL);
- finaltag.cpy(device.owner()->tag());
- }
- else
- device.subtag(finaltag, tag);
- return finaltag;
-}
-
static void init_port_state(running_machine &machine)
{
const char *joystick_map_default = machine.options().joystick_map();
@@ -2012,7 +1999,7 @@ static void init_port_state(running_machine &machine)
astring devicetag;
if (!field->read.isnull())
{
- *readdevicetail = init_field_device_info(field, get_device_tag(port->owner(), field->read_device, devicetag));
+ *readdevicetail = init_field_device_info(field, port->owner().subtag(devicetag, field->read_device));
field->read.late_bind(*(*readdevicetail)->device);
readdevicetail = &(*readdevicetail)->next;
}
@@ -2020,7 +2007,7 @@ static void init_port_state(running_machine &machine)
/* if this entry has device output, allocate memory for the tracking structure */
if (!field->write.isnull())
{
- *writedevicetail = init_field_device_info(field, get_device_tag(port->owner(), field->write_device, devicetag));
+ *writedevicetail = init_field_device_info(field, port->owner().subtag(devicetag, field->write_device));
field->write.late_bind(*(*writedevicetail)->device);
writedevicetail = &(*writedevicetail)->next;
}
@@ -2028,7 +2015,7 @@ static void init_port_state(running_machine &machine)
/* if this entry has device output, allocate memory for the tracking structure */
if (!field->crossmapper.isnull())
{
- device_t *device = machine.device(get_device_tag(port->owner(), field->crossmapper_device, devicetag));
+ device_t *device = machine.device(port->owner().subtag(devicetag, field->crossmapper_device));
field->crossmapper.late_bind(*device);
}
@@ -2842,16 +2829,13 @@ static int frame_get_digital_field_state(const input_field_config *field, int mo
UINT32 port_default_value(const char *fulltag, UINT32 mask, UINT32 defval, device_t &owner)
{
- astring tempstring;
- const input_device_default *def = NULL;
- def = owner.input_ports_defaults();
- if (def!=NULL) {
- while (def->tag!=NULL) {
- if ((strcmp(fulltag,owner.subtag(tempstring,def->tag))==0) && (def->mask == mask)) {
+ const input_device_default *def = owner.input_ports_defaults();
+ if (def != NULL)
+ {
+ astring fullpath;
+ for ( ; def->tag != NULL; def++)
+ if (owner.subtag(fullpath, def->tag) == fulltag && def->mask == mask)
return def->defvalue;
- }
- def++;
- }
}
return defval;
}
@@ -4830,6 +4814,7 @@ input_port_config *ioconfig_alloc_port(ioport_list &portlist, device_t &device,
{
astring fulltag;
device.subtag(fulltag, tag);
+mame_printf_verbose("ioport '%s' created\n", fulltag.cstr());
return &portlist.append(fulltag, *global_alloc(input_port_config(device, fulltag)));
}
diff --git a/src/emu/ioport.h b/src/emu/ioport.h
index 25ca0aa17cf..1d70ac210f0 100644
--- a/src/emu/ioport.h
+++ b/src/emu/ioport.h
@@ -1333,7 +1333,7 @@ input_port_value input_port_read_direct(const input_port_config *port);
input_port_value input_port_read(running_machine &machine, const char *tag);
/* return the value of a device input port specified by tag */
-input_port_value input_port_read(device_t *device, const char *tag);
+input_port_value input_port_read(device_t &device, const char *tag);
/* return the value of an input port specified by tag, or a default value if the port does not exist */
input_port_value input_port_read_safe(running_machine &machine, const char *tag, input_port_value defvalue);
diff --git a/src/emu/machine.c b/src/emu/machine.c
index 172f15e31a5..4118d3b0370 100644
--- a/src/emu/machine.c
+++ b/src/emu/machine.c
@@ -150,7 +150,6 @@ running_machine::running_machine(const machine_config &_config, osd_interface &o
memory_data(NULL),
palette_data(NULL),
romload_data(NULL),
- input_data(NULL),
input_port_data(NULL),
ui_input_data(NULL),
debugcpu_data(NULL),
@@ -171,7 +170,6 @@ running_machine::running_machine(const machine_config &_config, osd_interface &o
m_video(NULL),
m_tilemap(NULL),
m_debug_view(NULL),
- m_driver_device(NULL),
m_current_phase(MACHINE_PHASE_PREINIT),
m_paused(false),
m_hard_reset_pending(false),
@@ -194,21 +192,19 @@ running_machine::running_machine(const machine_config &_config, osd_interface &o
memset(&m_base_time, 0, sizeof(m_base_time));
// set the machine on all devices
- const_cast<device_list &>(devicelist()).set_machine_all(*this);
-
- // find the driver device config and tell it which game
- m_driver_device = device<driver_device>("root");
- if (m_driver_device == NULL)
- throw emu_fatalerror("Machine configuration missing driver_device");
+ device_iterator iter(root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
+ device->set_machine(*this);
// find devices
- primary_screen = downcast<screen_device *>(devicelist().first(SCREEN));
- for (device_t *device = devicelist().first(); device != NULL; device = device->next())
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
if (dynamic_cast<cpu_device *>(device) != NULL)
{
firstcpu = downcast<cpu_device *>(device);
break;
}
+ screen_device_iterator screeniter(root_device());
+ primary_screen = screeniter.first();
// fetch core options
if (options().debug())
@@ -318,8 +314,12 @@ void running_machine::start()
// so this location in the init order is important
ui_set_startup_text(*this, "Initializing...", true);
- // start up the devices
- const_cast<device_list &>(devicelist()).start_all();
+ // register callbacks for the devices, then start them
+ add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(running_machine::reset_all_devices), this));
+ add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(running_machine::stop_all_devices), this));
+ save().register_presave(save_prepost_delegate(FUNC(running_machine::presave_all_devices), this));
+ save().register_postload(save_prepost_delegate(FUNC(running_machine::postload_all_devices), this));
+ start_all_devices();
// if we're coming in with a savegame request, process it now
const char *savegame = options().state();
@@ -344,25 +344,15 @@ void running_machine::start()
device_t &running_machine::add_dynamic_device(device_t &owner, device_type type, const char *tag, UINT32 clock)
{
- // allocate and append this device
- astring fulltag;
- owner.subtag(fulltag, tag);
- device_t &device = const_cast<device_list &>(devicelist()).append(fulltag, *type(m_config, fulltag, &owner, clock));
-
- // append any machine config additions from new devices
- for (device_t *curdevice = devicelist().first(); curdevice != NULL; curdevice = curdevice->next())
- if (!curdevice->configured())
- {
- machine_config_constructor machconfig = curdevice->machine_config_additions();
- if (machconfig != NULL)
- (*machconfig)(const_cast<machine_config &>(m_config), curdevice);
- }
-
- // notify any new devices that their configurations are complete
- for (device_t *curdevice = devicelist().first(); curdevice != NULL; curdevice = curdevice->next())
- if (!curdevice->configured())
- curdevice->config_complete();
- return device;
+ // add the device in a standard manner
+ device_t *device = const_cast<machine_config &>(m_config).device_add(&owner, tag, type, clock);
+
+ // notify this device and all its subdevices that they are now configured
+ device_iterator iter(root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
+ if (!device->configured())
+ device->config_complete();
+ return *device;
}
@@ -633,6 +623,7 @@ void running_machine::resume()
memory_region *running_machine::region_alloc(const char *name, UINT32 length, UINT8 width, endianness_t endian)
{
+mame_printf_verbose("Region '%s' created\n", name);
// make sure we don't have a region of the same name; also find the end of the list
memory_region *info = m_regionlist.find(name);
if (info != NULL)
@@ -887,6 +878,115 @@ void running_machine::logfile_callback(running_machine &machine, const char *buf
machine.m_logfile->puts(buffer);
}
+
+//-------------------------------------------------
+// start_all_devices - start any unstarted devices
+//-------------------------------------------------
+
+void running_machine::start_all_devices()
+{
+ // iterate through the devices
+ int last_failed_starts = -1;
+ while (last_failed_starts != 0)
+ {
+ // iterate over all devices
+ int failed_starts = 0;
+ device_iterator iter(root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
+ if (!device->started())
+ {
+ // attempt to start the device, catching any expected exceptions
+ try
+ {
+ // if the device doesn't have a machine yet, set it first
+ if (device->m_machine == NULL)
+ device->set_machine(*this);
+
+ // now start the device
+ mame_printf_verbose("Starting %s '%s'\n", device->name(), device->tag());
+ device->start();
+ }
+
+ // handle missing dependencies by moving the device to the end
+ catch (device_missing_dependencies &)
+ {
+ // if we're the end, fail
+ mame_printf_verbose(" (missing dependencies; rescheduling)\n");
+ failed_starts++;
+ }
+ }
+
+ // each iteration should reduce the number of failed starts; error if
+ // this doesn't happen
+ if (failed_starts == last_failed_starts)
+ throw emu_fatalerror("Circular dependency in device startup!");
+ last_failed_starts = failed_starts;
+ }
+}
+
+
+//-------------------------------------------------
+// reset_all_devices - reset all devices in the
+// hierarchy
+//-------------------------------------------------
+
+void running_machine::reset_all_devices()
+{
+ // iterate over devices and reset them
+ device_iterator iter(root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
+ device->reset();
+}
+
+
+//-------------------------------------------------
+// stop_all_devices - stop all the devices in the
+// hierarchy
+//-------------------------------------------------
+
+void running_machine::stop_all_devices()
+{
+ // first let the debugger save comments
+ if ((debug_flags & DEBUG_FLAG_ENABLED) != 0)
+ debug_comment_save(*this);
+
+ // iterate over devices and stop them
+ device_iterator iter(root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
+ device->stop();
+
+ // then nuke the device tree
+// global_free(m_root_device);
+}
+
+
+//-------------------------------------------------
+// presave_all_devices - tell all the devices we
+// are about to save
+//-------------------------------------------------
+
+void running_machine::presave_all_devices()
+{
+ device_iterator iter(root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
+ device->pre_save();
+}
+
+
+//-------------------------------------------------
+// postload_all_devices - tell all the devices we
+// just completed a load
+//-------------------------------------------------
+
+void running_machine::postload_all_devices()
+{
+ device_iterator iter(root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
+ device->post_load();
+}
+
+
+
/***************************************************************************
MEMORY REGIONS
***************************************************************************/
@@ -1143,8 +1243,10 @@ ioport_constructor driver_device::device_input_ports() const
void driver_device::device_start()
{
// reschedule ourselves to be last
- if (next() != NULL)
- throw device_missing_dependencies();
+ device_iterator iter(*this);
+ for (device_t *test = iter.first(); test != NULL; test = iter.next())
+ if (test != this && !test->started())
+ throw device_missing_dependencies();
// call the game-specific init
if (m_system->driver_init != NULL)
diff --git a/src/emu/machine.h b/src/emu/machine.h
index f80d60ef84a..dbaf69f93fc 100644
--- a/src/emu/machine.h
+++ b/src/emu/machine.h
@@ -186,7 +186,6 @@ class osd_interface;
typedef struct _memory_private memory_private;
typedef struct _palette_private palette_private;
typedef struct _romload_private romload_private;
-typedef struct _input_private input_private;
typedef struct _input_port_private input_port_private;
typedef struct _ui_input_private ui_input_private;
typedef struct _debugcpu_private debugcpu_private;
@@ -331,7 +330,7 @@ public:
// getters
const machine_config &config() const { return m_config; }
- const device_list &devicelist() const { return m_config.devicelist(); }
+ device_t &root_device() const { return m_config.root_device(); }
const game_driver &system() const { return m_system; }
osd_interface &osd() const { return m_osd; }
resource_pool &respool() { return m_respool; }
@@ -344,8 +343,8 @@ public:
video_manager &video() const { assert(m_video != NULL); return *m_video; }
tilemap_manager &tilemap() const { assert(m_tilemap != NULL); return *m_tilemap; }
debug_view_manager &debug_view() const { assert(m_debug_view != NULL); return *m_debug_view; }
- driver_device *driver_data() const { return m_driver_device; }
- template<class _DriverClass> _DriverClass *driver_data() const { return downcast<_DriverClass *>(m_driver_device); }
+ driver_device *driver_data() const { return &downcast<driver_device &>(root_device()); }
+ template<class _DriverClass> _DriverClass *driver_data() const { return &downcast<_DriverClass &>(root_device()); }
machine_phase phase() const { return m_current_phase; }
bool paused() const { return m_paused || (m_current_phase != MACHINE_PHASE_RUNNING); }
bool exit_pending() const { return m_exit_pending; }
@@ -364,7 +363,7 @@ public:
bool scheduled_event_pending() const { return m_exit_pending || m_hard_reset_pending; }
// fetch items by name
- inline device_t *device(const char *tag);
+ inline device_t *device(const char *tag) { return root_device().subdevice(tag); }
template<class _DeviceClass> inline _DeviceClass *device(const char *tag) { return downcast<_DeviceClass *>(device(tag)); }
inline const input_port_config *port(const char *tag);
inline const memory_region *region(const char *tag);
@@ -408,7 +407,7 @@ public:
ioport_list m_portlist; // points to a list of input port configurations
// CPU information
- cpu_device * firstcpu; // first CPU (allows for quick iteration via typenext)
+ cpu_device * firstcpu; // first CPU
// video-related information
gfx_element * gfx[MAX_GFX_ELEMENTS];// array of pointers to graphic sets (chars, sprites)
@@ -419,7 +418,7 @@ public:
const pen_t * pens; // remapped palette pen numbers
colortable_t * colortable; // global colortable for remapping
pen_t * shadow_table; // table for looking up a shadowed pen
- bitmap_ind8 priority_bitmap; // priority bitmap
+ bitmap_ind8 priority_bitmap; // priority bitmap
// debugger-related information
UINT32 debug_flags; // the current debug flags
@@ -431,7 +430,6 @@ public:
memory_private * memory_data; // internal data from memory.c
palette_private * palette_data; // internal data from palette.c
romload_private * romload_data; // internal data from romload.c
- input_private * input_data; // internal data from input.c
input_port_private * input_port_data; // internal data from inptport.c
ui_input_private * ui_input_data; // internal data from uiinput.c
debugcpu_private * debugcpu_data; // internal data from debugcpu.c
@@ -446,10 +444,17 @@ private:
void fill_systime(system_time &systime, time_t t);
void handle_saveload();
void soft_reset(void *ptr = NULL, INT32 param = 0);
-
+
// internal callbacks
static void logfile_callback(running_machine &machine, const char *buffer);
+ // internal device helpers
+ void start_all_devices();
+ void reset_all_devices();
+ void stop_all_devices();
+ void presave_all_devices();
+ void postload_all_devices();
+
// internal state
const machine_config & m_config; // reference to the constructed machine_config
const game_driver & m_system; // reference to the definition of the game machine
@@ -469,9 +474,6 @@ private:
tilemap_manager * m_tilemap; // internal data from tilemap.c
debug_view_manager * m_debug_view; // internal data from debugvw.c
- // driver state
- driver_device * m_driver_device; // pointer to the current driver device
-
// system state
machine_phase m_current_phase; // current execution phase
bool m_paused; // paused?
@@ -716,25 +718,26 @@ device_t *driver_device_creator(const machine_config &mconfig, const char *tag,
// INLINE FUNCTIONS
//**************************************************************************
-inline device_t *running_machine::device(const char *tag)
-{
- return devicelist().find(tag);
-}
-
inline const input_port_config *running_machine::port(const char *tag)
{
- return m_portlist.find(tag);
+ // if tag begins with a :, it's absolute
+ if (tag[0] == ':')
+ return m_portlist.find(tag);
+
+ // otherwise, compute it relative to the root device
+ astring fulltag;
+ return m_portlist.find(root_device().subtag(fulltag, tag).cstr());
}
inline const memory_region *running_machine::region(const char *tag)
{
// if tag begins with a :, it's absolute
if (tag[0] == ':')
- {
- return m_regionlist.find(&tag[1]);
- }
+ return m_regionlist.find(tag);
- return m_regionlist.find(tag);
+ // otherwise, compute it relative to the root device
+ astring fulltag;
+ return m_regionlist.find(root_device().subtag(fulltag, tag).cstr());
}
diff --git a/src/emu/machine/6532riot.c b/src/emu/machine/6532riot.c
index da5bcc2105f..c8a2dfcdbb1 100644
--- a/src/emu/machine/6532riot.c
+++ b/src/emu/machine/6532riot.c
@@ -469,7 +469,8 @@ void riot6532_device::device_start()
assert(this != NULL);
/* set static values */
- m_index = machine().devicelist().indexof(RIOT6532, tag());
+ device_type_iterator<&device_creator<riot6532_device>, riot6532_device> iter(machine().root_device());
+ m_index = iter.indexof(*this);
/* configure the ports */
m_port[0].m_in_func.resolve(m_in_a_cb, *this);
diff --git a/src/emu/machine/7474.c b/src/emu/machine/7474.c
index 5a9c957cc57..0c5570913a9 100644
--- a/src/emu/machine/7474.c
+++ b/src/emu/machine/7474.c
@@ -86,7 +86,7 @@ void ttl7474_device::static_set_output_cb(device_t &device, write_line_device_fu
if (callback != NULL)
{
ttl7474.m_output_cb.type = DEVCB_TYPE_DEVICE;
- ttl7474.m_output_cb.index = DEVCB_DEVICE_OTHER;
+ ttl7474.m_output_cb.index = 0;
ttl7474.m_output_cb.writeline = callback;
}
else
@@ -105,7 +105,7 @@ void ttl7474_device::static_set_comp_output_cb(device_t &device, write_line_devi
if (callback != NULL)
{
ttl7474.m_comp_output_cb.type = DEVCB_TYPE_DEVICE;
- ttl7474.m_comp_output_cb.index = DEVCB_DEVICE_OTHER;
+ ttl7474.m_comp_output_cb.index = 0;
ttl7474.m_comp_output_cb.writeline = callback;
}
else
diff --git a/src/emu/machine/at28c16.c b/src/emu/machine/at28c16.c
index 1101b3ee8e4..bfb66894cec 100644
--- a/src/emu/machine/at28c16.c
+++ b/src/emu/machine/at28c16.c
@@ -65,9 +65,8 @@ void at28c16_device::device_config_complete()
// on this device
//-------------------------------------------------
-bool at28c16_device::device_validity_check( emu_options &options, const game_driver &driver ) const
+void at28c16_device::device_validity_check(validity_checker &valid) const
{
- return false;
}
diff --git a/src/emu/machine/at28c16.h b/src/emu/machine/at28c16.h
index a891d51881b..d81fe6abe0e 100644
--- a/src/emu/machine/at28c16.h
+++ b/src/emu/machine/at28c16.h
@@ -52,7 +52,7 @@ public:
protected:
// device-level overrides
virtual void device_config_complete();
- virtual bool device_validity_check( emu_options &options, const game_driver &driver ) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
diff --git a/src/emu/machine/ctronics.c b/src/emu/machine/ctronics.c
index 2fb045b8894..a06cf944c8b 100644
--- a/src/emu/machine/ctronics.c
+++ b/src/emu/machine/ctronics.c
@@ -101,7 +101,7 @@ static DEVICE_START( centronics )
centronics->strobe = TRUE;
/* get printer device */
- centronics->printer = downcast<printer_image_device *>(device->subdevice("printer"));
+ centronics->printer = device->subdevice<printer_image_device>("printer");
/* resolve callbacks */
centronics->out_ack_func.resolve(intf->out_ack_func, *device);
diff --git a/src/emu/machine/eeprom.c b/src/emu/machine/eeprom.c
index 129c9968c11..11929be6b77 100644
--- a/src/emu/machine/eeprom.c
+++ b/src/emu/machine/eeprom.c
@@ -170,17 +170,10 @@ void eeprom_device::static_set_default_value(device_t &device, UINT16 value)
// on this device
//-------------------------------------------------
-bool eeprom_device::device_validity_check(emu_options &options, const game_driver &driver) const
+void eeprom_device::device_validity_check(validity_checker &valid) const
{
- bool error = false;
-
if (m_data_bits != 8 && m_data_bits != 16)
- {
- mame_printf_error("%s: %s eeprom device '%s' specified invalid data width %d\n", driver.source_file, driver.name, tag(), m_data_bits);
- error = true;
- }
-
- return error;
+ mame_printf_error("Invalid data width %d specified\n", m_data_bits);
}
diff --git a/src/emu/machine/eeprom.h b/src/emu/machine/eeprom.h
index 31c44d15ec1..c7605dec4db 100644
--- a/src/emu/machine/eeprom.h
+++ b/src/emu/machine/eeprom.h
@@ -86,7 +86,7 @@ public:
protected:
// device-level overrides
- virtual bool device_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
diff --git a/src/emu/machine/generic.c b/src/emu/machine/generic.c
index 5a809bdb158..ba6192d3c91 100644
--- a/src/emu/machine/generic.c
+++ b/src/emu/machine/generic.c
@@ -94,9 +94,9 @@ void generic_machine_init(running_machine &machine)
// map devices to the interrupt state
memset(state->interrupt_device, 0, sizeof(state->interrupt_device));
- device_execute_interface *exec = NULL;
+ execute_interface_iterator iter(machine.root_device());
int index = 0;
- for (bool gotone = machine.devicelist().first(exec); gotone && index < ARRAY_LENGTH(state->interrupt_device); gotone = exec->next(exec))
+ for (device_execute_interface *exec = iter.first(); exec != NULL && index < ARRAY_LENGTH(state->interrupt_device); exec = iter.next())
state->interrupt_device[index++] = &exec->device();
/* register coin save state */
@@ -364,23 +364,18 @@ void nvram_load(running_machine &machine)
}
}
- device_nvram_interface *nvram = NULL;
- if (machine.devicelist().first(nvram))
+ nvram_interface_iterator iter(machine.root_device());
+ for (device_nvram_interface *nvram = iter.first(); nvram != NULL; nvram = iter.next())
{
- for (bool gotone = (nvram != NULL); gotone; gotone = nvram->next(nvram))
+ astring filename;
+ emu_file file(machine.options().nvram_directory(), OPEN_FLAG_READ);
+ if (file.open(nvram_filename(nvram->device(),filename)) == FILERR_NONE)
{
- astring filename;
- emu_file file(machine.options().nvram_directory(), OPEN_FLAG_READ);
- if (file.open(nvram_filename(nvram->device(),filename)) == FILERR_NONE)
- {
- nvram->nvram_load(file);
- file.close();
- }
- else
- {
- nvram->nvram_reset();
- }
+ nvram->nvram_load(file);
+ file.close();
}
+ else
+ nvram->nvram_reset();
}
}
@@ -402,18 +397,15 @@ void nvram_save(running_machine &machine)
}
}
- device_nvram_interface *nvram = NULL;
- if (machine.devicelist().first(nvram))
+ nvram_interface_iterator iter(machine.root_device());
+ for (device_nvram_interface *nvram = iter.first(); nvram != NULL; nvram = iter.next())
{
- for (bool gotone = (nvram != NULL); gotone; gotone = nvram->next(nvram))
+ astring filename;
+ emu_file file(machine.options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
+ if (file.open(nvram_filename(nvram->device(),filename)) == FILERR_NONE)
{
- astring filename;
- emu_file file(machine.options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(nvram_filename(nvram->device(),filename)) == FILERR_NONE)
- {
- nvram->nvram_save(file);
- file.close();
- }
+ nvram->nvram_save(file);
+ file.close();
}
}
}
diff --git a/src/emu/machine/i2cmem.c b/src/emu/machine/i2cmem.c
index 0aaacf24026..288a430de7c 100644
--- a/src/emu/machine/i2cmem.c
+++ b/src/emu/machine/i2cmem.c
@@ -125,10 +125,8 @@ void i2cmem_device::device_config_complete()
// on this device
//-------------------------------------------------
-bool i2cmem_device::device_validity_check( emu_options &options, const game_driver &driver ) const
+void i2cmem_device::device_validity_check(validity_checker &valid) const
{
- bool error = false;
- return error;
}
diff --git a/src/emu/machine/i2cmem.h b/src/emu/machine/i2cmem.h
index f0c6aa14deb..1dded6826fd 100644
--- a/src/emu/machine/i2cmem.h
+++ b/src/emu/machine/i2cmem.h
@@ -70,7 +70,7 @@ public:
protected:
// device-level overrides
virtual void device_config_complete();
- virtual bool device_validity_check( emu_options &options, const game_driver &driver ) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
diff --git a/src/emu/machine/i8243.c b/src/emu/machine/i8243.c
index cf1355585eb..cb1650413d2 100644
--- a/src/emu/machine/i8243.c
+++ b/src/emu/machine/i8243.c
@@ -41,7 +41,8 @@ void i8243_device::static_set_read_handler(device_t &device, read8_device_func c
if(callback != NULL)
{
i8243.m_readhandler_cb.type = DEVCB_TYPE_DEVICE;
- i8243.m_readhandler_cb.index = DEVCB_DEVICE_SELF;
+ i8243.m_readhandler_cb.index = 0;
+ i8243.m_readhandler_cb.tag = "";
i8243.m_readhandler_cb.readdevice = callback;
}
else
@@ -62,7 +63,8 @@ void i8243_device::static_set_write_handler(device_t &device, write8_device_func
if(callback != NULL)
{
i8243.m_writehandler_cb.type = DEVCB_TYPE_DEVICE;
- i8243.m_writehandler_cb.index = DEVCB_DEVICE_SELF;
+ i8243.m_writehandler_cb.index = 0;
+ i8243.m_writehandler_cb.tag = "";
i8243.m_writehandler_cb.writedevice = callback;
}
else
diff --git a/src/emu/machine/laserdsc.h b/src/emu/machine/laserdsc.h
index 185b2296586..b7c0df154e9 100644
--- a/src/emu/machine/laserdsc.h
+++ b/src/emu/machine/laserdsc.h
@@ -380,6 +380,9 @@ private:
render_texture * m_overtex; // texture for the overlay
};
+// iterator - interface iterator works for subclasses too
+typedef device_interface_iterator<laserdisc_device> laserdisc_device_iterator;
+
//**************************************************************************
diff --git a/src/emu/machine/mb3773.c b/src/emu/machine/mb3773.c
index 925def0a33f..cfe37d36eb7 100644
--- a/src/emu/machine/mb3773.c
+++ b/src/emu/machine/mb3773.c
@@ -47,9 +47,8 @@ void mb3773_device::device_config_complete()
// on this device
//-------------------------------------------------
-bool mb3773_device::device_validity_check( emu_options &options, const game_driver &driver ) const
+void mb3773_device::device_validity_check(validity_checker &valid) const
{
- return false;
}
diff --git a/src/emu/machine/mb3773.h b/src/emu/machine/mb3773.h
index 24874b3f534..b139477f2dc 100644
--- a/src/emu/machine/mb3773.h
+++ b/src/emu/machine/mb3773.h
@@ -35,7 +35,7 @@ public:
protected:
// device-level overrides
virtual void device_config_complete();
- virtual bool device_validity_check( emu_options &options, const game_driver &driver ) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
diff --git a/src/emu/machine/msm6242.c b/src/emu/machine/msm6242.c
index dd7bda24758..cc859c84e28 100644
--- a/src/emu/machine/msm6242.c
+++ b/src/emu/machine/msm6242.c
@@ -121,10 +121,8 @@ TIMER_CALLBACK( msm6242_device::rtc_inc_callback )
// on this device
//-------------------------------------------------
-bool msm6242_device::device_validity_check(emu_options &options, const game_driver &driver) const
+void msm6242_device::device_validity_check(validity_checker &valid) const
{
- bool error = false;
- return error;
}
//-------------------------------------------------
diff --git a/src/emu/machine/msm6242.h b/src/emu/machine/msm6242.h
index 3addb6b9df9..21b57dc1f5e 100644
--- a/src/emu/machine/msm6242.h
+++ b/src/emu/machine/msm6242.h
@@ -55,7 +55,7 @@ public:
protected:
// device-level overrides
virtual void device_config_complete();
- virtual bool device_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
diff --git a/src/emu/machine/ram.c b/src/emu/machine/ram.c
index 3c69f5e54dd..7c9648dbc47 100644
--- a/src/emu/machine/ram.c
+++ b/src/emu/machine/ram.c
@@ -75,38 +75,32 @@ void ram_device::device_start()
// checks
//-------------------------------------------------
-bool ram_device::device_validity_check(emu_options &options, const game_driver &driver) const
+void ram_device::device_validity_check(validity_checker &valid) const
{
const char *ramsize_string = NULL;
int is_valid = FALSE;
UINT32 specified_ram = 0;
- bool error = FALSE;
const char *gamename_option = NULL;
/* verify default ram value */
if (default_size() == 0)
- {
- mame_printf_error("%s: '%s' has an invalid default RAM option: %s\n", driver.source_file, driver.name, m_default_size);
- error = TRUE;
- }
+ mame_printf_error("Invalid default RAM option: %s\n", m_default_size);
/* command line options are only parsed for the device named RAM_TAG */
if (tag() != NULL && strcmp(tag(), RAM_TAG) == 0)
{
/* verify command line ram option */
- ramsize_string = options.ram_size();
- gamename_option = options.system_name();
+ ramsize_string = mconfig().options().ram_size();
+ gamename_option = mconfig().options().system_name();
if ((ramsize_string != NULL) && (ramsize_string[0] != '\0'))
{
specified_ram = parse_string(ramsize_string);
if (specified_ram == 0)
- {
- mame_printf_error("%s: '%s' cannot recognize the RAM option %s\n", driver.source_file, driver.name, ramsize_string);
- error = TRUE;
- }
- if (gamename_option != NULL && *gamename_option != 0 && strcmp(gamename_option, driver.name) == 0)
+ mame_printf_error("Cannot recognize the RAM option %s\n", ramsize_string);
+
+ if (gamename_option != NULL && *gamename_option != 0 && strcmp(gamename_option, mconfig().gamedrv().name) == 0)
{
/* compare command line option to default value */
if (default_size() == specified_ram)
@@ -130,10 +124,7 @@ bool ram_device::device_validity_check(emu_options &options, const game_driver &
UINT32 option_ram_size = parse_string(p);
if (option_ram_size == 0)
- {
- mame_printf_error("%s: '%s' has an invalid RAM option: %s\n", driver.source_file, driver.name, p);
- error = TRUE;
- }
+ mame_printf_error("Invalid RAM option: %s\n", p);
if (option_ram_size == specified_ram)
is_valid = TRUE;
@@ -163,18 +154,17 @@ bool ram_device::device_validity_check(emu_options &options, const game_driver &
if (!is_valid)
{
- mame_printf_error("%s: '%s' cannot recognize the RAM option %s", driver.source_file, driver.name, ramsize_string);
- mame_printf_error(" (valid options are %s", m_default_size);
+ astring output;
+ output.catprintf("Cannot recognize the RAM option %s", ramsize_string);
+ output.catprintf(" (valid options are %s", m_default_size);
if (m_extra_options != NULL)
- mame_printf_error(",%s).\n", m_extra_options);
+ output.catprintf(",%s).\n", m_extra_options);
else
- mame_printf_error(").\n");
+ output.catprintf(").\n");
- error = TRUE;
+ mame_printf_error("%s", output.cstr());
}
-
- return error;
}
diff --git a/src/emu/machine/ram.h b/src/emu/machine/ram.h
index 43a363aa0ca..238d7dcfabd 100644
--- a/src/emu/machine/ram.h
+++ b/src/emu/machine/ram.h
@@ -65,7 +65,7 @@ public:
protected:
virtual void device_start(void);
- virtual bool device_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void device_validity_check(validity_checker &valid) const;
private:
// device state
@@ -82,4 +82,7 @@ private:
// device type definition
extern const device_type RAM;
+// device iterator
+typedef device_type_iterator<&device_creator<ram_device>, ram_device> ram_device_iterator;
+
#endif /* __RAM_H__ */
diff --git a/src/emu/machine/rtc9701.c b/src/emu/machine/rtc9701.c
index 2ac36ee0072..7812a858696 100644
--- a/src/emu/machine/rtc9701.c
+++ b/src/emu/machine/rtc9701.c
@@ -81,10 +81,8 @@ TIMER_CALLBACK( rtc9701_device::rtc_inc_callback )
// on this device
//-------------------------------------------------
-bool rtc9701_device::device_validity_check(emu_options &options, const game_driver &driver) const
+void rtc9701_device::device_validity_check(validity_checker &valid) const
{
- bool error = false;
- return error;
}
//-------------------------------------------------
diff --git a/src/emu/machine/rtc9701.h b/src/emu/machine/rtc9701.h
index 4d633167e66..9c5b96be74c 100644
--- a/src/emu/machine/rtc9701.h
+++ b/src/emu/machine/rtc9701.h
@@ -62,7 +62,7 @@ public:
protected:
// device-level overrides
- virtual bool device_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
diff --git a/src/emu/machine/scsihd.c b/src/emu/machine/scsihd.c
index 606350800b1..05f372aa6e9 100644
--- a/src/emu/machine/scsihd.c
+++ b/src/emu/machine/scsihd.c
@@ -279,7 +279,8 @@ static void scsihd_alloc_instance( SCSIInstance *scsiInstance, const char *diskr
if (our_this->disk == NULL)
{
// try to locate the CHD from an image subdevice
- for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(machine.root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
{
if (device->subdevice(diskregion) != NULL)
{
diff --git a/src/emu/machine/v3021.c b/src/emu/machine/v3021.c
index 66b788a36f1..13d2d5796a4 100644
--- a/src/emu/machine/v3021.c
+++ b/src/emu/machine/v3021.c
@@ -78,10 +78,8 @@ TIMER_CALLBACK( v3021_device::rtc_inc_callback )
// on this device
//-------------------------------------------------
-bool v3021_device::device_validity_check(emu_options &options, const game_driver &driver) const
+void v3021_device::device_validity_check(validity_checker &valid) const
{
- bool error = false;
- return error;
}
//-------------------------------------------------
diff --git a/src/emu/machine/v3021.h b/src/emu/machine/v3021.h
index 9a8bec9c3b2..af826448fbd 100644
--- a/src/emu/machine/v3021.h
+++ b/src/emu/machine/v3021.h
@@ -48,7 +48,7 @@ public:
protected:
// device-level overrides
- virtual bool device_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
diff --git a/src/emu/machine/wd17xx.c b/src/emu/machine/wd17xx.c
index b1e9b5e4beb..b0d19483609 100644
--- a/src/emu/machine/wd17xx.c
+++ b/src/emu/machine/wd17xx.c
@@ -1247,14 +1247,7 @@ void wd17xx_set_drive(device_t *device, UINT8 drive)
if (w->intf->floppy_drive_tags[drive] != NULL)
{
- if (device->owner() != NULL) {
- w->drive = device->owner()->subdevice(w->intf->floppy_drive_tags[drive]);
- if (w->drive == NULL) {
- w->drive = device->machine().device(w->intf->floppy_drive_tags[drive]);
- }
- }
- else
- w->drive = device->machine().device(w->intf->floppy_drive_tags[drive]);
+ w->drive = device->siblingdevice(w->intf->floppy_drive_tags[drive]);
}
}
@@ -2083,14 +2076,7 @@ static DEVICE_RESET( wd1770 )
if(w->intf->floppy_drive_tags[i]!=NULL) {
device_t *img = NULL;
- if (device->owner() != NULL)
- img = device->owner()->subdevice(w->intf->floppy_drive_tags[i]);
- if (img == NULL) {
- img = device->machine().device(w->intf->floppy_drive_tags[i]);
- }
-
- else
- img = device->machine().device(w->intf->floppy_drive_tags[i]);
+ img = device->siblingdevice(w->intf->floppy_drive_tags[i]);
if (img!=NULL) {
floppy_drive_set_controller(img,device);
diff --git a/src/emu/mame.c b/src/emu/mame.c
index 5407fe4c2d6..c5a523251a6 100644
--- a/src/emu/mame.c
+++ b/src/emu/mame.c
@@ -104,8 +104,21 @@ static bool print_verbose = false;
static running_machine *global_machine;
/* output channels */
-static output_callback_func output_cb[OUTPUT_CHANNEL_COUNT];
-static void *output_cb_param[OUTPUT_CHANNEL_COUNT];
+static output_delegate output_cb[OUTPUT_CHANNEL_COUNT] =
+{
+ output_delegate(FUNC(mame_file_output_callback), stderr), // OUTPUT_CHANNEL_ERROR
+ output_delegate(FUNC(mame_file_output_callback), stderr), // OUTPUT_CHANNEL_WARNING
+ output_delegate(FUNC(mame_file_output_callback), stdout), // OUTPUT_CHANNEL_INFO
+#ifdef MAME_DEBUG
+ output_delegate(FUNC(mame_file_output_callback), stdout), // OUTPUT_CHANNEL_DEBUG
+#else
+ output_delegate(FUNC(mame_null_output_callback), stdout), // OUTPUT_CHANNEL_DEBUG
+#endif
+ output_delegate(FUNC(mame_file_output_callback), stdout), // OUTPUT_CHANNEL_VERBOSE
+ output_delegate(FUNC(mame_file_output_callback), stdout) // OUTPUT_CHANNEL_LOG
+};
+
+
/***************************************************************************
CORE IMPLEMENTATION
@@ -151,7 +164,10 @@ int mame_execute(emu_options &options, osd_interface &osd)
// otherwise, perform validity checks before anything else
else
- validate_drivers(options, system);
+ {
+ validity_checker valid(options);
+ valid.check_shared_source(*system);
+ }
firstgame = false;
@@ -203,20 +219,17 @@ int mame_execute(emu_options &options, osd_interface &osd)
channel
-------------------------------------------------*/
-void mame_set_output_channel(output_channel channel, output_callback_func callback, void *param, output_callback_func *prevcb, void **prevparam)
+output_delegate mame_set_output_channel(output_channel channel, output_delegate callback)
{
assert(channel < OUTPUT_CHANNEL_COUNT);
- assert(callback != NULL);
+ assert(!callback.isnull());
/* return the originals if requested */
- if (prevcb != NULL)
- *prevcb = output_cb[channel];
- if (prevparam != NULL)
- *prevparam = output_cb_param[channel];
+ output_delegate prevcb = output_cb[channel];
/* set the new ones */
output_cb[channel] = callback;
- output_cb_param[channel] = param;
+ return prevcb;
}
@@ -225,9 +238,9 @@ void mame_set_output_channel(output_channel channel, output_callback_func callba
for file output
-------------------------------------------------*/
-void mame_file_output_callback(void *param, const char *format, va_list argptr)
+void mame_file_output_callback(FILE *param, const char *format, va_list argptr)
{
- vfprintf((FILE *)param, format, argptr);
+ vfprintf(param, format, argptr);
}
@@ -236,7 +249,7 @@ void mame_file_output_callback(void *param, const char *format, va_list argptr)
for no output
-------------------------------------------------*/
-void mame_null_output_callback(void *param, const char *format, va_list argptr)
+void mame_null_output_callback(FILE *param, const char *format, va_list argptr)
{
}
@@ -250,16 +263,9 @@ void mame_printf_error(const char *format, ...)
{
va_list argptr;
- /* by default, we go to stderr */
- if (output_cb[OUTPUT_CHANNEL_ERROR] == NULL)
- {
- output_cb[OUTPUT_CHANNEL_ERROR] = mame_file_output_callback;
- output_cb_param[OUTPUT_CHANNEL_ERROR] = stderr;
- }
-
/* do the output */
va_start(argptr, format);
- (*output_cb[OUTPUT_CHANNEL_ERROR])(output_cb_param[OUTPUT_CHANNEL_ERROR], format, argptr);
+ output_cb[OUTPUT_CHANNEL_ERROR](format, argptr);
va_end(argptr);
}
@@ -273,16 +279,9 @@ void mame_printf_warning(const char *format, ...)
{
va_list argptr;
- /* by default, we go to stderr */
- if (output_cb[OUTPUT_CHANNEL_WARNING] == NULL)
- {
- output_cb[OUTPUT_CHANNEL_WARNING] = mame_file_output_callback;
- output_cb_param[OUTPUT_CHANNEL_WARNING] = stderr;
- }
-
/* do the output */
va_start(argptr, format);
- (*output_cb[OUTPUT_CHANNEL_WARNING])(output_cb_param[OUTPUT_CHANNEL_WARNING], format, argptr);
+ output_cb[OUTPUT_CHANNEL_WARNING](format, argptr);
va_end(argptr);
}
@@ -296,16 +295,9 @@ void mame_printf_info(const char *format, ...)
{
va_list argptr;
- /* by default, we go to stdout */
- if (output_cb[OUTPUT_CHANNEL_INFO] == NULL)
- {
- output_cb[OUTPUT_CHANNEL_INFO] = mame_file_output_callback;
- output_cb_param[OUTPUT_CHANNEL_INFO] = stdout;
- }
-
/* do the output */
va_start(argptr, format);
- (*output_cb[OUTPUT_CHANNEL_INFO])(output_cb_param[OUTPUT_CHANNEL_INFO], format, argptr);
+ output_cb[OUTPUT_CHANNEL_INFO](format, argptr);
va_end(argptr);
}
@@ -323,16 +315,9 @@ void mame_printf_verbose(const char *format, ...)
if (!print_verbose)
return;
- /* by default, we go to stdout */
- if (output_cb[OUTPUT_CHANNEL_VERBOSE] == NULL)
- {
- output_cb[OUTPUT_CHANNEL_VERBOSE] = mame_file_output_callback;
- output_cb_param[OUTPUT_CHANNEL_VERBOSE] = stdout;
- }
-
/* do the output */
va_start(argptr, format);
- (*output_cb[OUTPUT_CHANNEL_VERBOSE])(output_cb_param[OUTPUT_CHANNEL_VERBOSE], format, argptr);
+ output_cb[OUTPUT_CHANNEL_VERBOSE](format, argptr);
va_end(argptr);
}
@@ -346,21 +331,9 @@ void mame_printf_debug(const char *format, ...)
{
va_list argptr;
- /* by default, we go to stderr */
- if (output_cb[OUTPUT_CHANNEL_DEBUG] == NULL)
- {
-#ifdef MAME_DEBUG
- output_cb[OUTPUT_CHANNEL_DEBUG] = mame_file_output_callback;
- output_cb_param[OUTPUT_CHANNEL_DEBUG] = stdout;
-#else
- output_cb[OUTPUT_CHANNEL_DEBUG] = mame_null_output_callback;
- output_cb_param[OUTPUT_CHANNEL_DEBUG] = NULL;
-#endif
- }
-
/* do the output */
va_start(argptr, format);
- (*output_cb[OUTPUT_CHANNEL_DEBUG])(output_cb_param[OUTPUT_CHANNEL_DEBUG], format, argptr);
+ output_cb[OUTPUT_CHANNEL_DEBUG](format, argptr);
va_end(argptr);
}
@@ -375,16 +348,9 @@ void mame_printf_log(const char *format, ...)
{
va_list argptr;
- /* by default, we go to stderr */
- if (output_cb[OUTPUT_CHANNEL_LOG] == NULL)
- {
- output_cb[OUTPUT_CHANNEL_LOG] = mame_file_output_callback;
- output_cb_param[OUTPUT_CHANNEL_LOG] = stderr;
- }
-
/* do the output */
va_start(argptr, format);
- (*output_cb[OUTPUT_CHANNEL_LOG])(output_cb_param[OUTPUT_CHANNEL_LOG], format, argptr);
+ output_cb[OUTPUT_CHANNEL_LOG])(format, argptr);
va_end(argptr);
}
#endif
diff --git a/src/emu/mame.h b/src/emu/mame.h
index 13b51c696fc..cdec7d1db1f 100644
--- a/src/emu/mame.h
+++ b/src/emu/mame.h
@@ -49,7 +49,7 @@ enum
//**************************************************************************
// output channel callback
-typedef void (*output_callback_func)(void *param, const char *format, va_list argptr);
+typedef delegate<void (const char *, va_list)> output_delegate;
class emulator_info
{
@@ -76,6 +76,8 @@ public:
static void printf_usage(const char *par1, const char *par2);
};
+
+
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
@@ -102,11 +104,11 @@ int mame_is_valid_machine(running_machine &machine);
/* ----- output management ----- */
/* set the output handler for a channel, returns the current one */
-void mame_set_output_channel(output_channel channel, output_callback_func callback, void *param, output_callback_func *prevcb, void **prevparam);
+output_delegate mame_set_output_channel(output_channel channel, output_delegate callback);
/* built-in default callbacks */
-void mame_file_output_callback(void *param, const char *format, va_list argptr);
-void mame_null_output_callback(void *param, const char *format, va_list argptr);
+void mame_file_output_callback(FILE *file, const char *format, va_list argptr);
+void mame_null_output_callback(FILE *param, const char *format, va_list argptr);
/* calls to be used by the code */
void mame_printf_error(const char *format, ...) ATTR_PRINTF(1,2);
diff --git a/src/emu/mconfig.c b/src/emu/mconfig.c
index 6ef83f2e0ec..43c76b7ee7f 100644
--- a/src/emu/mconfig.c
+++ b/src/emu/mconfig.c
@@ -62,14 +62,15 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options)
m_total_colors(0),
m_default_layout(NULL),
m_gamedrv(gamedrv),
- m_options(options)
+ m_options(options),
+ m_root_device(NULL)
{
// construct the config
(*gamedrv.machine_config)(*this, NULL);
// intialize slot devices - make sure that any required devices have been allocated
- device_slot_interface *slot = NULL;
- for (bool gotone = m_devicelist.first(slot); gotone; gotone = slot->next(slot))
+ slot_interface_iterator slotiter(root_device());
+ for (device_slot_interface *slot = slotiter.first(); slot != NULL; slot = slotiter.next())
{
const slot_interface *intf = slot->get_slot_interfaces();
if (intf != NULL)
@@ -77,16 +78,19 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options)
device_t &owner = slot->device();
const char *selval = options.value(owner.tag());
if (!options.exists(owner.tag()))
- selval = slot->get_default_card(devicelist(), options);
+ selval = slot->get_default_card(*this, options);
- if (selval != NULL && strlen(selval)!=0) {
+ if (selval != NULL && strlen(selval) != 0)
+ {
bool found = false;
- for (int i = 0; intf[i].name != NULL; i++) {
- if (strcmp(selval, intf[i].name) == 0) {
+ for (int i = 0; intf[i].name != NULL; i++)
+ {
+ if (strcmp(selval, intf[i].name) == 0)
+ {
device_t *new_dev = device_add(&owner, intf[i].name, intf[i].devtype, 0);
found = true;
- const char *def = slot->get_default_card(devicelist(), options);
- if ((def!=NULL) && (strcmp(def,selval)==0))
+ const char *def = slot->get_default_card(*this, options);
+ if (def != NULL && strcmp(def, selval) == 0)
device_t::static_set_input_default(*new_dev, slot->input_ports_defaults());
}
}
@@ -97,13 +101,11 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options)
}
// when finished, set the game driver
- device_t *root = m_devicelist.find("root");
- if (root == NULL)
- throw emu_fatalerror("Machine configuration missing driver_device");
- driver_device::static_set_game(*root, gamedrv);
+ driver_device::static_set_game(*m_root_device, gamedrv);
// then notify all devices that their configuration is complete
- for (device_t *device = m_devicelist.first(); device != NULL; device = device->next())
+ device_iterator iter(root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
if (!device->configured())
device->config_complete();
}
@@ -115,6 +117,7 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options)
machine_config::~machine_config()
{
+ global_free(m_root_device);
}
@@ -125,46 +128,8 @@ machine_config::~machine_config()
screen_device *machine_config::first_screen() const
{
- return downcast<screen_device *>(m_devicelist.first(SCREEN));
-}
-
-
-//-------------------------------------------------
-// device_add_subdevices - helper to add
-// devices owned by the device
-//-------------------------------------------------
-
-void machine_config::device_add_subdevices(device_t *device)
-{
- machine_config_constructor additions = device->machine_config_additions();
- if (additions != NULL)
- (*additions)(*this, device);
-}
-
-
-//-------------------------------------------------
-// device_remove_subdevices - helper to remove
-// devices owned by the device
-//-------------------------------------------------
-
-void machine_config::device_remove_subdevices(const device_t *device)
-{
- if (device != NULL)
- {
- device_t *sub_device = m_devicelist.first();
- while (sub_device != NULL)
- {
- if (sub_device->owner() == device)
- device_remove_subdevices(sub_device);
-
- device_t *next_device = sub_device->next();
-
- if (sub_device->owner() == device)
- m_devicelist.remove(*sub_device);
-
- sub_device = next_device;
- }
- }
+ screen_device_iterator iter(root_device());
+ return iter.first();
}
@@ -175,11 +140,19 @@ void machine_config::device_remove_subdevices(const device_t *device)
device_t *machine_config::device_add(device_t *owner, const char *tag, device_type type, UINT32 clock)
{
- astring tempstring;
- const char *fulltag = owner->subtag(tempstring, tag);
- device_t *device = &m_devicelist.append(fulltag, *(*type)(*this, fulltag, owner, clock));
- device_add_subdevices(device);
- return device;
+ // if there's an owner, let the owner do the work
+ if (owner != NULL)
+ return owner->add_subdevice(type, tag, clock);
+
+ // otherwise, allocate the device directly
+ assert(m_root_device == NULL);
+ m_root_device = (*type)(*this, tag, owner, clock);
+
+ // apply any machine configuration owned by the device now
+ machine_config_constructor additions = m_root_device->machine_config_additions();
+ if (additions != NULL)
+ (*additions)(*this, m_root_device);
+ return m_root_device;
}
@@ -190,12 +163,17 @@ device_t *machine_config::device_add(device_t *owner, const char *tag, device_ty
device_t *machine_config::device_replace(device_t *owner, const char *tag, device_type type, UINT32 clock)
{
- astring tempstring;
- const char *fulltag = owner->subtag(tempstring, tag);
- device_remove_subdevices(m_devicelist.find(fulltag));
- device_t *device = &m_devicelist.replace_and_remove(fulltag, *(*type)(*this, fulltag, owner, clock));
- device_add_subdevices(device);
- return device;
+ // find the original device by this name (must exist)
+ assert(owner != NULL);
+ device_t *device = owner->subdevice(tag);
+ if (device == NULL)
+ {
+ mame_printf_warning("Warning: attempting to replace non-existent device '%s'\n", tag);
+ return device_add(owner, tag, type, clock);
+ }
+
+ // let the device's owner do the work
+ return device->owner()->replace_subdevice(*device, type, tag, clock);
}
@@ -206,11 +184,17 @@ device_t *machine_config::device_replace(device_t *owner, const char *tag, devic
device_t *machine_config::device_remove(device_t *owner, const char *tag)
{
- astring tempstring;
- const char *fulltag = owner->subtag(tempstring, tag);
- device_t *device=m_devicelist.find(fulltag);
- device_remove_subdevices(device);
- m_devicelist.remove(*device);
+ // find the original device by this name (must exist)
+ assert(owner != NULL);
+ device_t *device = owner->subdevice(tag);
+ if (device == NULL)
+ {
+ mame_printf_warning("Warning: attempting to remove non-existent device '%s'\n", tag);
+ return NULL;
+ }
+
+ // let the device's owner do the work
+ device->owner()->remove_subdevice(*device);
return NULL;
}
@@ -222,10 +206,13 @@ device_t *machine_config::device_remove(device_t *owner, const char *tag)
device_t *machine_config::device_find(device_t *owner, const char *tag)
{
- astring tempstring;
- const char *fulltag = owner->subtag(tempstring, tag);
- device_t *device = m_devicelist.find(fulltag);
+ // find the original device by this name (must exist)
+ assert(owner != NULL);
+ device_t *device = owner->subdevice(tag);
+ assert(device != NULL);
if (device == NULL)
- throw emu_fatalerror("Unable to find device: tag=%s\n", fulltag);
+ throw emu_fatalerror("Unable to find device '%s'\n", tag);
+
+ // return the device
return device;
}
diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h
index e4b619eba2a..73f7770cf92 100644
--- a/src/emu/mconfig.h
+++ b/src/emu/mconfig.h
@@ -131,10 +131,11 @@ public:
// getters
const game_driver &gamedrv() const { return m_gamedrv; }
- const device_list &devicelist() const { return m_devicelist; }
- const device_t *first_device() const { return m_devicelist.first(); }
+ device_t &root_device() const { assert(m_root_device != NULL); return *m_root_device; }
screen_device *first_screen() const;
emu_options &options() const { return m_options; }
+ inline device_t *device(const char *tag) const { return root_device().subdevice(tag); }
+ template<class _DeviceClass> inline _DeviceClass *device(const char *tag) const { return downcast<_DeviceClass *>(device(tag)); }
// public state
attotime m_minimum_quantum; // minimum scheduling quantum
@@ -142,9 +143,11 @@ public:
INT32 m_watchdog_vblank_count; // number of VBLANKs until the watchdog kills us
attotime m_watchdog_time; // length of time until the watchdog kills us
+ // legacy callbacks
nvram_handler_func m_nvram_handler; // NVRAM save/load callback
memcard_handler_func m_memcard_handler; // memory card save/load callback
+ // other parameters
UINT32 m_video_attributes; // flags describing the video system
const gfx_decode_entry *m_gfxdecodeinfo; // pointer to array of graphics decoding information
UINT32 m_total_colors; // total number of colors in the palette
@@ -157,12 +160,10 @@ public:
device_t *device_find(device_t *owner, const char *tag);
private:
- void device_add_subdevices(device_t *device);
- void device_remove_subdevices(const device_t *device);
-
+ // internal state
const game_driver & m_gamedrv;
emu_options & m_options;
- device_list m_devicelist; // list of device configs
+ device_t * m_root_device;
};
diff --git a/src/emu/memory.c b/src/emu/memory.c
index dd11e6dd51c..521eb09d871 100644
--- a/src/emu/memory.c
+++ b/src/emu/memory.c
@@ -1726,8 +1726,8 @@ void memory_init(running_machine &machine)
memdata->banknext = STATIC_BANK1;
// loop over devices and spaces within each device
- device_memory_interface *memory = NULL;
- for (bool gotone = machine.devicelist().first(memory); gotone; gotone = memory->next(memory))
+ memory_interface_iterator iter(machine.root_device());
+ for (device_memory_interface *memory = iter.first(); memory != NULL; memory = iter.next())
for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++)
{
// if there is a configuration for this space, we need an address space
@@ -1781,10 +1781,22 @@ address_space *memory_nonspecific_space(running_machine &machine)
void memory_configure_bank(running_machine &machine, const char *tag, int startentry, int numentries, void *base, offs_t stride)
{
+ memory_configure_bank(machine.root_device(), tag, startentry, numentries, base, stride);
+}
+
+
+//-------------------------------------------------
+// memory_configure_bank - configure the
+// addresses for a bank
+//-------------------------------------------------
+
+void memory_configure_bank(device_t &device, const char *tag, int startentry, int numentries, void *base, offs_t stride)
+{
// validation checks
- memory_bank *bank = machine.memory_data->bankmap.find_hash_only(tag);
+ astring fulltag;
+ memory_bank *bank = device.machine().memory_data->bankmap.find_hash_only(device.subtag(fulltag, tag));
if (bank == NULL)
- fatalerror("memory_configure_bank called for unknown bank '%s'", tag);
+ fatalerror("memory_configure_bank called for unknown bank '%s'", fulltag.cstr());
if (base == NULL)
fatalerror("memory_configure_bank called NULL base");
@@ -1795,14 +1807,13 @@ void memory_configure_bank(running_machine &machine, const char *tag, int starte
//-------------------------------------------------
-// memory_configure_bank - configure the
-// addresses for a bank
+// memory_configure_bank_decrypted - configure
+// the decrypted addresses for a bank
//-------------------------------------------------
-void memory_configure_bank(device_t *device, const char *tag, int startentry, int numentries, void *base, offs_t stride)
+void memory_configure_bank_decrypted(running_machine &machine, const char *tag, int startentry, int numentries, void *base, offs_t stride)
{
- astring tempstring;
- memory_configure_bank(device->machine(), device->subtag(tempstring, tag), startentry, numentries, base, stride);
+ memory_configure_bank_decrypted(machine.root_device(), tag, startentry, numentries, base, stride);
}
@@ -1811,12 +1822,13 @@ void memory_configure_bank(device_t *device, const char *tag, int startentry, in
// the decrypted addresses for a bank
//-------------------------------------------------
-void memory_configure_bank_decrypted(running_machine &machine, const char *tag, int startentry, int numentries, void *base, offs_t stride)
+void memory_configure_bank_decrypted(device_t &device, const char *tag, int startentry, int numentries, void *base, offs_t stride)
{
// validation checks
- memory_bank *bank = machine.memory_data->bankmap.find_hash_only(tag);
+ astring fulltag;
+ memory_bank *bank = device.machine().memory_data->bankmap.find_hash_only(device.subtag(fulltag, tag));
if (bank == NULL)
- fatalerror("memory_configure_bank_decrypted called for unknown bank '%s'", tag);
+ fatalerror("memory_configure_bank_decrypted called for unknown bank '%s'", fulltag.cstr());
if (base == NULL)
fatalerror("memory_configure_bank_decrypted called NULL base");
@@ -1827,14 +1839,13 @@ void memory_configure_bank_decrypted(running_machine &machine, const char *tag,
//-------------------------------------------------
-// memory_configure_bank_decrypted - configure
-// the decrypted addresses for a bank
+// memory_set_bank - select one pre-configured
+// entry to be the new bank base
//-------------------------------------------------
-void memory_configure_bank_decrypted(device_t *device, const char *tag, int startentry, int numentries, void *base, offs_t stride)
+void memory_set_bank(running_machine &machine, const char *tag, int entrynum)
{
- astring tempstring;
- memory_configure_bank_decrypted(device->machine(), device->subtag(tempstring, tag), startentry, numentries, base, stride);
+ memory_set_bank(machine.root_device(), tag, entrynum);
}
@@ -1843,12 +1854,13 @@ void memory_configure_bank_decrypted(device_t *device, const char *tag, int star
// entry to be the new bank base
//-------------------------------------------------
-void memory_set_bank(running_machine &machine, const char *tag, int entrynum)
+void memory_set_bank(device_t &device, const char *tag, int entrynum)
{
// validation checks
- memory_bank *bank = machine.memory_data->bankmap.find_hash_only(tag);
+ astring fulltag;
+ memory_bank *bank = device.machine().memory_data->bankmap.find_hash_only(device.subtag(fulltag, tag));
if (bank == NULL)
- fatalerror("memory_set_bank called for unknown bank '%s'", tag);
+ fatalerror("memory_set_bank called for unknown bank '%s'", fulltag.cstr());
// set the base
bank->set_entry(entrynum);
@@ -1856,14 +1868,13 @@ void memory_set_bank(running_machine &machine, const char *tag, int entrynum)
//-------------------------------------------------
-// memory_set_bank - select one pre-configured
-// entry to be the new bank base
+// memory_get_bank - return the currently
+// selected bank
//-------------------------------------------------
-void memory_set_bank(device_t *device, const char *tag, int entrynum)
+int memory_get_bank(running_machine &machine, const char *tag)
{
- astring tempstring;
- memory_set_bank(device->machine(), device->subtag(tempstring, tag), entrynum);
+ return memory_get_bank(machine.root_device(), tag);
}
@@ -1872,12 +1883,13 @@ void memory_set_bank(device_t *device, const char *tag, int entrynum)
// selected bank
//-------------------------------------------------
-int memory_get_bank(running_machine &machine, const char *tag)
+int memory_get_bank(device_t &device, const char *tag)
{
// validation checks
- memory_bank *bank = machine.memory_data->bankmap.find_hash_only(tag);
+ astring fulltag;
+ memory_bank *bank = device.machine().memory_data->bankmap.find_hash_only(device.subtag(fulltag, tag));
if (bank == NULL)
- fatalerror("memory_get_bank called for unknown bank '%s'", tag);
+ fatalerror("memory_get_bank called for unknown bank '%s'", fulltag.cstr());
// return the current entry
return bank->entry();
@@ -1885,14 +1897,12 @@ int memory_get_bank(running_machine &machine, const char *tag)
//-------------------------------------------------
-// memory_get_bank - return the currently
-// selected bank
+// memory_set_bankptr - set the base of a bank
//-------------------------------------------------
-int memory_get_bank(device_t *device, const char *tag)
+void memory_set_bankptr(running_machine &machine, const char *tag, void *base)
{
- astring tempstring;
- return memory_get_bank(device->machine(), device->subtag(tempstring, tag));
+ memory_set_bankptr(machine.root_device(), tag, base);
}
@@ -1900,12 +1910,13 @@ int memory_get_bank(device_t *device, const char *tag)
// memory_set_bankptr - set the base of a bank
//-------------------------------------------------
-void memory_set_bankptr(running_machine &machine, const char *tag, void *base)
+void memory_set_bankptr(device_t &device, const char *tag, void *base)
{
// validation checks
- memory_bank *bank = machine.memory_data->bankmap.find_hash_only(tag);
+ astring fulltag;
+ memory_bank *bank = device.machine().memory_data->bankmap.find_hash_only(device.subtag(fulltag, tag));
if (bank == NULL)
- throw emu_fatalerror("memory_set_bankptr called for unknown bank '%s'", tag);
+ throw emu_fatalerror("memory_set_bankptr called for unknown bank '%s'", fulltag.cstr());
// set the base
bank->set_base(base);
@@ -1913,17 +1924,6 @@ void memory_set_bankptr(running_machine &machine, const char *tag, void *base)
//-------------------------------------------------
-// memory_set_bankptr - set the base of a bank
-//-------------------------------------------------
-
-void memory_set_bankptr(device_t *device, const char *tag, void *base)
-{
- astring tempstring;
- return memory_set_bankptr(device->machine(), device->subtag(tempstring, tag), base);
-}
-
-
-//-------------------------------------------------
// memory_get_shared - get a pointer to a shared
// memory region by tag
//-------------------------------------------------
@@ -1936,7 +1936,8 @@ void *memory_get_shared(running_machine &machine, const char *tag)
void *memory_get_shared(running_machine &machine, const char *tag, size_t &length)
{
- memory_share *share = machine.memory_data->sharemap.find(tag);
+ astring fulltag;
+ memory_share *share = machine.memory_data->sharemap.find(machine.root_device().subtag(fulltag, tag));
if (share == NULL)
return NULL;
length = share->size();
@@ -2186,11 +2187,16 @@ void address_space::prepare_map()
adjust_addresses(entry->m_bytestart, entry->m_byteend, entry->m_bytemask, entry->m_bytemirror);
// if we have a share entry, add it to our map
- if (entry->m_share != NULL && machine().memory_data->sharemap.find(entry->m_share) == NULL)
+ if (entry->m_share != NULL)
{
- VPRINTF(("Creating share '%s' of length 0x%X\n", entry->m_share, entry->m_byteend + 1 - entry->m_bytestart));
- memory_share *share = auto_alloc(machine(), memory_share(entry->m_byteend + 1 - entry->m_bytestart));
- machine().memory_data->sharemap.add(entry->m_share, share, false);
+ // if we can't find it, add it to our map
+ astring fulltag;
+ if (machine().memory_data->sharemap.find(device().siblingtag(fulltag, entry->m_share)) == NULL)
+ {
+ VPRINTF(("Creating share '%s' of length 0x%X\n", fulltag.cstr(), entry->m_byteend + 1 - entry->m_bytestart));
+ memory_share *share = auto_alloc(machine(), memory_share(entry->m_byteend + 1 - entry->m_bytestart));
+ machine().memory_data->sharemap.add(fulltag, share, false);
+ }
}
// if this is a ROM handler without a specified region, attach it to the implicit region
@@ -2207,22 +2213,12 @@ void address_space::prepare_map()
// validate adjusted addresses against implicit regions
if (entry->m_region != NULL && entry->m_share == NULL && entry->m_baseptr == NULL)
{
- astring regiontag;
+ // determine full tag
+ astring fulltag;
+ device().siblingtag(fulltag, entry->m_region);
- // a leading : on a region name indicates an absolute region, so fix up accordingly
- if (entry->m_region[0] == ':')
- {
- regiontag = &entry->m_region[1];
- }
- else
- {
- if (strchr(entry->m_region,':')) {
- regiontag = entry->m_region;
- } else {
- m_device.siblingtag(regiontag, entry->m_region);
- }
- }
- const memory_region *region = machine().region(regiontag.cstr());
+ // find the region
+ const memory_region *region = machine().region(fulltag);
if (region == NULL)
fatalerror("Error: device '%s' %s space memory map entry %X-%X references non-existant region \"%s\"", m_device.tag(), m_name, entry->m_addrstart, entry->m_addrend, entry->m_region);
@@ -2232,14 +2228,14 @@ void address_space::prepare_map()
}
// convert any region-relative entries to their memory pointers
- if (entry->m_region != NULL) {
- astring regiontag;
- if (strchr(entry->m_region,':')) {
- regiontag = entry->m_region;
- } else {
- m_device.siblingtag(regiontag, entry->m_region);
- }
- entry->m_memory = machine().region(regiontag.cstr())->base() + entry->m_rgnoffs;
+ if (entry->m_region != NULL)
+ {
+ // determine full tag
+ astring fulltag;
+ device().siblingtag(fulltag, entry->m_region);
+
+ // set the memory address
+ entry->m_memory = machine().region(fulltag.cstr())->base() + entry->m_rgnoffs;
}
}
@@ -2286,7 +2282,8 @@ void address_space::populate_from_map()
void address_space::populate_map_entry(const address_map_entry &entry, read_or_write readorwrite)
{
const map_handler_data &data = (readorwrite == ROW_READ) ? entry.m_read : entry.m_write;
- device_t *device;
+ device_t *target_device;
+ astring fulltag;
// based on the handler type, alter the bits, name, funcptr, and object
switch (data.m_type)
@@ -2313,25 +2310,25 @@ void address_space::populate_map_entry(const address_map_entry &entry, read_or_w
break;
case AMH_DEVICE_DELEGATE:
- device = machine().device(data.m_tag);
- if (device == NULL)
- throw emu_fatalerror("Attempted to map a non-existent device '%s' in space %s of device '%s'\n", data.m_tag, m_name, m_device.tag());
+ target_device = device().siblingdevice(data.m_tag);
+ if (target_device == NULL)
+ throw emu_fatalerror("Attempted to map a non-existent device '%s' in space %s of device '%s'\n", data.m_tag.cstr(), m_name, m_device.tag());
if (readorwrite == ROW_READ)
switch (data.m_bits)
{
- case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read8_delegate(entry.m_rproto8, *device), data.m_mask); break;
- case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read16_delegate(entry.m_rproto16, *device), data.m_mask); break;
- case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read32_delegate(entry.m_rproto32, *device), data.m_mask); break;
- case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read64_delegate(entry.m_rproto64, *device), data.m_mask); break;
+ case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read8_delegate(entry.m_rproto8, *target_device), data.m_mask); break;
+ case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read16_delegate(entry.m_rproto16, *target_device), data.m_mask); break;
+ case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read32_delegate(entry.m_rproto32, *target_device), data.m_mask); break;
+ case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read64_delegate(entry.m_rproto64, *target_device), data.m_mask); break;
}
else
switch (data.m_bits)
{
- case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write8_delegate(entry.m_wproto8, *device), data.m_mask); break;
- case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write16_delegate(entry.m_wproto16, *device), data.m_mask); break;
- case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write32_delegate(entry.m_wproto32, *device), data.m_mask); break;
- case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write64_delegate(entry.m_wproto64, *device), data.m_mask); break;
+ case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write8_delegate(entry.m_wproto8, *target_device), data.m_mask); break;
+ case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write16_delegate(entry.m_wproto16, *target_device), data.m_mask); break;
+ case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write32_delegate(entry.m_wproto32, *target_device), data.m_mask); break;
+ case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write64_delegate(entry.m_wproto64, *target_device), data.m_mask); break;
}
break;
@@ -2355,42 +2352,42 @@ void address_space::populate_map_entry(const address_map_entry &entry, read_or_w
break;
case AMH_LEGACY_DEVICE_HANDLER:
- device = machine().device(data.m_tag);
- if (device == NULL)
- fatalerror("Attempted to map a non-existent device '%s' in space %s of device '%s'\n", data.m_tag, m_name, m_device.tag());
+ target_device = device().siblingdevice(data.m_tag);
+ if (target_device == NULL)
+ fatalerror("Attempted to map a non-existent device '%s' in space %s of device '%s'\n", data.m_tag.cstr(), m_name, m_device.tag());
if (readorwrite == ROW_READ)
switch (data.m_bits)
{
- case 8: install_legacy_read_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice8, data.m_name, data.m_mask); break;
- case 16: install_legacy_read_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice16, data.m_name, data.m_mask); break;
- case 32: install_legacy_read_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice32, data.m_name, data.m_mask); break;
- case 64: install_legacy_read_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice64, data.m_name, data.m_mask); break;
+ case 8: install_legacy_read_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice8, data.m_name, data.m_mask); break;
+ case 16: install_legacy_read_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice16, data.m_name, data.m_mask); break;
+ case 32: install_legacy_read_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice32, data.m_name, data.m_mask); break;
+ case 64: install_legacy_read_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice64, data.m_name, data.m_mask); break;
}
else
switch (data.m_bits)
{
- case 8: install_legacy_write_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice8, data.m_name, data.m_mask); break;
- case 16: install_legacy_write_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice16, data.m_name, data.m_mask); break;
- case 32: install_legacy_write_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice32, data.m_name, data.m_mask); break;
- case 64: install_legacy_write_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice64, data.m_name, data.m_mask); break;
+ case 8: install_legacy_write_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice8, data.m_name, data.m_mask); break;
+ case 16: install_legacy_write_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice16, data.m_name, data.m_mask); break;
+ case 32: install_legacy_write_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice32, data.m_name, data.m_mask); break;
+ case 64: install_legacy_write_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice64, data.m_name, data.m_mask); break;
}
break;
case AMH_PORT:
install_readwrite_port(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror,
- (readorwrite == ROW_READ) ? data.m_tag : NULL,
- (readorwrite == ROW_WRITE) ? data.m_tag : NULL);
+ (readorwrite == ROW_READ) ? data.m_tag.cstr() : NULL,
+ (readorwrite == ROW_WRITE) ? data.m_tag.cstr() : NULL);
break;
case AMH_BANK:
install_bank_generic(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror,
- (readorwrite == ROW_READ) ? data.m_tag : NULL,
- (readorwrite == ROW_WRITE) ? data.m_tag : NULL);
+ (readorwrite == ROW_READ) ? data.m_tag.cstr() : NULL,
+ (readorwrite == ROW_WRITE) ? data.m_tag.cstr() : NULL);
break;
case AMH_DEVICE_SUBMAP:
- throw emu_fatalerror("Internal mapping error: leftover mapping of '%s'.\n", data.m_tag);
+ throw emu_fatalerror("Internal mapping error: leftover mapping of '%s'.\n", data.m_tag.cstr());
}
}
@@ -2478,13 +2475,13 @@ void address_space::locate_memory()
if (entry->m_baseptr != NULL)
*entry->m_baseptr = entry->m_memory;
if (entry->m_baseptroffs_plus1 != 0)
- *(void **)(reinterpret_cast<UINT8 *>(machine().driver_data<void>()) + entry->m_baseptroffs_plus1 - 1) = entry->m_memory;
+ *(void **)(reinterpret_cast<UINT8 *>(machine().driver_data()) + entry->m_baseptroffs_plus1 - 1) = entry->m_memory;
if (entry->m_genbaseptroffs_plus1 != 0)
*(void **)((UINT8 *)&machine().generic + entry->m_genbaseptroffs_plus1 - 1) = entry->m_memory;
if (entry->m_sizeptr != NULL)
*entry->m_sizeptr = entry->m_byteend - entry->m_bytestart + 1;
if (entry->m_sizeptroffs_plus1 != 0)
- *(size_t *)(reinterpret_cast<UINT8 *>(machine().driver_data<void>()) + entry->m_sizeptroffs_plus1 - 1) = entry->m_byteend - entry->m_bytestart + 1;
+ *(size_t *)(reinterpret_cast<UINT8 *>(machine().driver_data()) + entry->m_sizeptroffs_plus1 - 1) = entry->m_byteend - entry->m_bytestart + 1;
if (entry->m_gensizeptroffs_plus1 != 0)
*(size_t *)((UINT8 *)&machine().generic + entry->m_gensizeptroffs_plus1 - 1) = entry->m_byteend - entry->m_bytestart + 1;
}
@@ -2562,7 +2559,8 @@ address_map_entry *address_space::block_assign_intersecting(offs_t bytestart, of
// if we haven't assigned this block yet, see if we have a mapped shared pointer for it
if (entry->m_memory == NULL && entry->m_share != NULL)
{
- memory_share *share = memdata->sharemap.find(entry->m_share);
+ astring fulltag;
+ memory_share *share = memdata->sharemap.find(device().siblingtag(fulltag, entry->m_share));
if (share != NULL && share->ptr() != NULL)
{
entry->m_memory = share->ptr();
@@ -2584,7 +2582,8 @@ address_map_entry *address_space::block_assign_intersecting(offs_t bytestart, of
// if we're the first match on a shared pointer, assign it now
if (entry->m_memory != NULL && entry->m_share != NULL)
{
- memory_share *share = memdata->sharemap.find(entry->m_share);
+ astring fulltag;
+ memory_share *share = memdata->sharemap.find(device().siblingtag(fulltag, entry->m_share));
if (share != NULL && share->ptr() == NULL)
{
share->set_ptr(entry->m_memory);
@@ -2685,7 +2684,9 @@ void address_space::install_readwrite_port(offs_t addrstart, offs_t addrend, off
if (rtag != NULL)
{
// find the port
- const input_port_config *port = machine().port(rtag);
+ astring fulltag;
+ device().siblingtag(fulltag, rtag);
+ const input_port_config *port = machine().port(fulltag);
if (port == NULL)
throw emu_fatalerror("Attempted to map non-existent port '%s' for read in space %s of device '%s'\n", rtag, m_name, m_device.tag());
@@ -2696,7 +2697,9 @@ void address_space::install_readwrite_port(offs_t addrstart, offs_t addrend, off
if (wtag != NULL)
{
// find the port
- const input_port_config *port = machine().port(wtag);
+ astring fulltag;
+ device().siblingtag(fulltag, wtag);
+ const input_port_config *port = machine().port(fulltag);
if (port == NULL)
fatalerror("Attempted to map non-existent port '%s' for write in space %s of device '%s'\n", wtag, m_name, m_device.tag());
@@ -2724,14 +2727,18 @@ void address_space::install_bank_generic(offs_t addrstart, offs_t addrend, offs_
// map the read bank
if (rtag != NULL)
{
- memory_bank &bank = bank_find_or_allocate(rtag, addrstart, addrend, addrmask, addrmirror, ROW_READ);
+ astring fulltag;
+ device().siblingtag(fulltag, rtag);
+ memory_bank &bank = bank_find_or_allocate(fulltag, addrstart, addrend, addrmask, addrmirror, ROW_READ);
read().map_range(addrstart, addrend, addrmask, addrmirror, bank.index());
}
// map the write bank
if (wtag != NULL)
{
- memory_bank &bank = bank_find_or_allocate(wtag, addrstart, addrend, addrmask, addrmirror, ROW_WRITE);
+ astring fulltag;
+ device().siblingtag(fulltag, wtag);
+ memory_bank &bank = bank_find_or_allocate(fulltag, addrstart, addrend, addrmask, addrmirror, ROW_WRITE);
write().map_range(addrstart, addrend, addrmask, addrmirror, bank.index());
}
@@ -3224,7 +3231,8 @@ bool address_space::needs_backing_store(const address_map_entry *entry)
// if we are sharing, and we don't have a pointer yet, create one
if (entry->m_share != NULL)
{
- memory_share *share = machine().memory_data->sharemap.find(entry->m_share);
+ astring fulltag;
+ memory_share *share = machine().memory_data->sharemap.find(device().siblingtag(fulltag, entry->m_share));
if (share != NULL && share->ptr() == NULL)
return true;
}
diff --git a/src/emu/memory.h b/src/emu/memory.h
index ec45c6fb342..717b77eeaf5 100644
--- a/src/emu/memory.h
+++ b/src/emu/memory.h
@@ -676,23 +676,23 @@ void memory_init(running_machine &machine);
// configure the addresses for a bank
void memory_configure_bank(running_machine &machine, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(5);
-void memory_configure_bank(device_t *device, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(5);
+void memory_configure_bank(device_t &device, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(5);
// configure the decrypted addresses for a bank
void memory_configure_bank_decrypted(running_machine &machine, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(5);
-void memory_configure_bank_decrypted(device_t *device, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(5);
+void memory_configure_bank_decrypted(device_t &device, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(5);
// select one pre-configured entry to be the new bank base
void memory_set_bank(running_machine &machine, const char *tag, int entrynum);
-void memory_set_bank(device_t *device, const char *tag, int entrynum);
+void memory_set_bank(device_t &device, const char *tag, int entrynum);
// return the currently selected bank
int memory_get_bank(running_machine &machine, const char *tag);
-int memory_get_bank(device_t *device, const char *tag);
+int memory_get_bank(device_t &device, const char *tag);
// set the absolute address of a bank base
void memory_set_bankptr(running_machine &machine, const char *tag, void *base) ATTR_NONNULL(3);
-void memory_set_bankptr(device_t *device, const char *tag, void *base) ATTR_NONNULL(3);
+void memory_set_bankptr(device_t &device, const char *tag, void *base) ATTR_NONNULL(3);
// get a pointer to a shared memory region by tag
void *memory_get_shared(running_machine &machine, const char *tag);
diff --git a/src/emu/network.c b/src/emu/network.c
index cd44270c556..3da575835af 100644
--- a/src/emu/network.c
+++ b/src/emu/network.c
@@ -23,7 +23,6 @@
static void network_load(running_machine &machine, int config_type, xml_data_node *parentnode)
{
xml_data_node *node;
- device_network_interface *network = NULL;
if ((config_type == CONFIG_TYPE_GAME) && (parentnode != NULL))
{
for (node = xml_get_sibling(parentnode->child, "device"); node; node = xml_get_sibling(node->next, "device"))
@@ -32,7 +31,8 @@ static void network_load(running_machine &machine, int config_type, xml_data_nod
if ((tag != NULL) && (tag[0] != '\0'))
{
- for (bool gotone = machine.devicelist().first(network); gotone; gotone = network->next(network))
+ network_interface_iterator iter(machine.root_device());
+ for (device_network_interface *network = iter.first(); network != NULL; network = iter.next())
{
if (!strcmp(tag, network->device().tag())) {
int interface = xml_get_attribute_int(node, "interface", 0);
@@ -56,12 +56,12 @@ static void network_load(running_machine &machine, int config_type, xml_data_nod
static void network_save(running_machine &machine, int config_type, xml_data_node *parentnode)
{
xml_data_node *node;
- device_network_interface *network = NULL;
/* only care about game-specific data */
if (config_type == CONFIG_TYPE_GAME)
{
- for (bool gotone = machine.devicelist().first(network); gotone; gotone = network->next(network))
+ network_interface_iterator iter(machine.root_device());
+ for (device_network_interface *network = iter.first(); network != NULL; network = iter.next())
{
node = xml_add_child(parentnode, "device", NULL);
if (node != NULL)
diff --git a/src/emu/profiler.c b/src/emu/profiler.c
index c4c6e49a4e1..71b8735c052 100644
--- a/src/emu/profiler.c
+++ b/src/emu/profiler.c
@@ -233,6 +233,7 @@ const char *real_profiler_state::text(running_machine &machine, astring &string)
}
// loop over all types and generate the string
+ device_iterator iter(machine.root_device());
for (curtype = PROFILER_DEVICE_FIRST; curtype < PROFILER_TOTAL; curtype++)
{
// determine the accumulated time for this type
@@ -252,7 +253,7 @@ const char *real_profiler_state::text(running_machine &machine, astring &string)
// and then the text
if (curtype >= PROFILER_DEVICE_FIRST && curtype <= PROFILER_DEVICE_MAX)
- string.catprintf("'%s'", machine.devicelist().find(curtype - PROFILER_DEVICE_FIRST)->tag());
+ string.catprintf("'%s'", iter.byindex(curtype - PROFILER_DEVICE_FIRST)->tag());
else
for (int nameindex = 0; nameindex < ARRAY_LENGTH(names); nameindex++)
if (names[nameindex].type == curtype)
diff --git a/src/emu/render.c b/src/emu/render.c
index 0975c03f036..7f971618b25 100644
--- a/src/emu/render.c
+++ b/src/emu/render.c
@@ -1120,17 +1120,15 @@ int render_target::configured_view(const char *viewname, int targetindex, int nu
}
// if we don't have a match, default to the nth view
- int scrcount = m_manager.machine().devicelist().count(SCREEN);
+ screen_device_iterator iter(m_manager.machine().root_device());
+ int scrcount = iter.count();
if (view == NULL && scrcount > 0)
{
// if we have enough targets to be one per screen, assign in order
if (numtargets >= scrcount)
{
int ourindex = index() % scrcount;
- screen_device *screen;
- for (screen = m_manager.machine().first_screen(); screen != NULL; screen = screen->next_screen())
- if (ourindex-- == 0)
- break;
+ screen_device *screen = iter.byindex(ourindex);
// find the first view with this screen and this screen only
for (view = view_by_index(viewindex = 0); view != NULL; view = view_by_index(++viewindex))
@@ -1157,7 +1155,7 @@ int render_target::configured_view(const char *viewname, int targetindex, int nu
if (viewscreens.count() >= scrcount)
{
screen_device *screen;
- for (screen = m_manager.machine().first_screen(); screen != NULL; screen = screen->next_screen())
+ for (screen = iter.first(); screen != NULL; screen = iter.next())
if (!viewscreens.contains(*screen))
break;
if (screen == NULL)
@@ -1576,7 +1574,8 @@ void render_target::load_layout_files(const char *layoutfile, bool singlefile)
else
have_default |= true;
}
- int screens = m_manager.machine().devicelist().count(SCREEN);
+ screen_device_iterator iter(m_manager.machine().root_device());
+ int screens = iter.count();
// now do the built-in layouts for single-screen games
if (screens == 1)
{
@@ -2432,7 +2431,8 @@ render_manager::render_manager(running_machine &machine)
config_register(machine, "video", config_saveload_delegate(FUNC(render_manager::config_load), this), config_saveload_delegate(FUNC(render_manager::config_save), this));
// create one container per screen
- for (screen_device *screen = machine.first_screen(); screen != NULL; screen = screen->next_screen())
+ screen_device_iterator iter(machine.root_device());
+ for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next())
screen->set_container(*container_alloc(screen));
}
diff --git a/src/emu/rendlay.c b/src/emu/rendlay.c
index 64db4b26c36..7bad91878dc 100644
--- a/src/emu/rendlay.c
+++ b/src/emu/rendlay.c
@@ -203,10 +203,10 @@ static int get_variable_value(running_machine &machine, const char *string, char
char temp[100];
// screen 0 parameters
- for (const screen_device *device = machine.first_screen(); device != NULL; device = device->next_screen())
+ screen_device_iterator iter(machine.root_device());
+ int scrnum = 0;
+ for (const screen_device *device = iter.first(); device != NULL; device = iter.next(), scrnum++)
{
- int scrnum = machine.devicelist().indexof(SCREEN, device->tag());
-
// native X aspect factor
sprintf(temp, "~scr%dnativexaspect~", scrnum);
if (!strncmp(string, temp, strlen(temp)))
@@ -1863,7 +1863,10 @@ layout_view::item::item(running_machine &machine, xml_data_node &itemnode, simpl
// fetch common data
int index = xml_get_attribute_int_with_subst(machine, itemnode, "index", -1);
if (index != -1)
- m_screen = downcast<screen_device *>(machine.devicelist().find(SCREEN, index));
+ {
+ screen_device_iterator iter(machine.root_device());
+ m_screen = iter.byindex(index);
+ }
m_input_mask = xml_get_attribute_int_with_subst(machine, itemnode, "inputmask", 0);
if (m_output_name[0] != 0 && m_element != NULL)
output_set_value(m_output_name, m_element->default_state());
diff --git a/src/emu/romload.c b/src/emu/romload.c
index b350e8d6d54..9289d692189 100644
--- a/src/emu/romload.c
+++ b/src/emu/romload.c
@@ -188,7 +188,8 @@ void set_disk_handle(running_machine &machine, const char *region, emu_file &fil
const rom_source *rom_first_source(const machine_config &config)
{
/* look through devices */
- for (const device_t *device = config.devicelist().first(); device != NULL; device = device->next())
+ device_iterator iter(config.root_device());
+ for (const device_t *device = iter.first(); device != NULL; device = iter.next())
if (device->rom_region() != NULL)
return device;
@@ -204,9 +205,16 @@ const rom_source *rom_first_source(const machine_config &config)
const rom_source *rom_next_source(const rom_source &previous)
{
/* look for further devices with ROM definitions */
- for (const device_t *device = previous.next(); device != NULL; device = device->next())
+// fixme: this is awful
+ device_iterator iter(previous.mconfig().root_device());
+ const device_t *device;
+ for (device = iter.first(); device != NULL; device = iter.next())
+ if (device == &previous)
+ break;
+
+ for (device = iter.next(); device != NULL; device = iter.next())
if (device->rom_region() != NULL)
- return (rom_source *)device;
+ return device;
return NULL;
}
@@ -273,7 +281,7 @@ const rom_entry *rom_next_file(const rom_entry *romp)
astring &rom_region_name(astring &result, const game_driver *drv, const rom_source *source, const rom_entry *romp)
{
- return source->subtag(result, ROMREGION_GETTAG(romp));
+ return source->subtag(result, ROM_GETNAME(romp));
}
diff --git a/src/emu/schedule.c b/src/emu/schedule.c
index 614ed8bdacb..741ae074896 100644
--- a/src/emu/schedule.c
+++ b/src/emu/schedule.c
@@ -788,8 +788,8 @@ void device_scheduler::rebuild_execute_list()
device_execute_interface **suspend_tailptr = &suspend_list;
// iterate over all devices
- device_execute_interface *exec = NULL;
- for (bool gotone = machine().devicelist().first(exec); gotone; gotone = exec->next(exec))
+ execute_interface_iterator iter(machine().root_device());
+ for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
{
// append to the appropriate list
exec->m_nextexec = NULL;
diff --git a/src/emu/screen.c b/src/emu/screen.c
index 4bd2b8ebc39..aab40d9fced 100644
--- a/src/emu/screen.c
+++ b/src/emu/screen.c
@@ -244,42 +244,26 @@ void screen_device::static_set_screen_vblank(device_t &device, screen_vblank_del
// configuration
//-------------------------------------------------
-bool screen_device::device_validity_check(emu_options &options, const game_driver &driver) const
+void screen_device::device_validity_check(validity_checker &valid) const
{
- bool error = false;
-
// sanity check dimensions
if (m_width <= 0 || m_height <= 0)
- {
- mame_printf_error("%s: %s screen '%s' has invalid display dimensions\n", driver.source_file, driver.name, tag());
- error = true;
- }
+ mame_printf_error("Invalid display dimensions\n");
// sanity check display area
if (m_type != SCREEN_TYPE_VECTOR)
{
if (m_visarea.empty() || m_visarea.max_x >= m_width || m_visarea.max_y >= m_height)
- {
- mame_printf_error("%s: %s screen '%s' has an invalid display area\n", driver.source_file, driver.name, tag());
- error = true;
- }
+ mame_printf_error("Invalid display area\n");
// sanity check screen formats
if (m_screen_update_ind16.isnull() && m_screen_update_rgb32.isnull())
- {
- mame_printf_error("%s: %s screen '%s' has no SCREEN_UPDATE function\n", driver.source_file, driver.name, tag());
- error = true;
- }
+ mame_printf_error("Missing SCREEN_UPDATE function\n");
}
// check for zero frame rate
if (m_refresh == 0)
- {
- mame_printf_error("%s: %s screen '%s' has a zero refresh rate\n", driver.source_file, driver.name, tag());
- error = true;
- }
-
- return error;
+ mame_printf_error("Invalid (zero) refresh rate\n");
}
diff --git a/src/emu/screen.h b/src/emu/screen.h
index e9f496e11ba..aeb927f8143 100644
--- a/src/emu/screen.h
+++ b/src/emu/screen.h
@@ -192,7 +192,6 @@ public:
static void static_set_screen_vblank(device_t &device, screen_vblank_delegate callback);
// information getters
- screen_device *next_screen() const { return downcast<screen_device *>(typenext()); }
render_container &container() const { assert(m_container != NULL); return *m_container; }
// dynamic configuration
@@ -244,7 +243,7 @@ private:
};
// device-level overrides
- virtual bool device_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_stop();
virtual void device_post_load();
@@ -334,6 +333,9 @@ private:
// device type definition
extern const device_type SCREEN;
+// iterator helper
+typedef device_type_iterator<&device_creator<screen_device>, screen_device> screen_device_iterator;
+
//**************************************************************************
diff --git a/src/emu/softlist.c b/src/emu/softlist.c
index 1bb5dd3dc2d..c3470d897c2 100644
--- a/src/emu/softlist.c
+++ b/src/emu/softlist.c
@@ -17,6 +17,63 @@
typedef tagmap_t<software_info *> softlist_map;
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+tagmap_t<UINT8> software_list_device::s_checked_lists;
+
+// device type definition
+const device_type SOFTWARE_LIST = &device_creator<software_list_device>;
+
+//-------------------------------------------------
+// software_list_device - constructor
+//-------------------------------------------------
+
+software_list_device::software_list_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, SOFTWARE_LIST, "Software lists", tag, owner, clock),
+ m_list_name(NULL),
+ m_list_type(SOFTWARE_LIST_ORIGINAL_SYSTEM),
+ m_filter(NULL)
+{
+}
+
+
+//-------------------------------------------------
+// static_set_interface - configuration helper
+// to set the interface
+//-------------------------------------------------
+
+void software_list_device::static_set_config(device_t &device, const char *list, softlist_type list_type)
+{
+ software_list_device &softlist = downcast<software_list_device &>(device);
+ softlist.m_list_name = list;
+ softlist.m_list_type = list_type;
+}
+
+
+//-------------------------------------------------
+// static_set_custom_handler - configuration
+// helper to set a custom callback
+//-------------------------------------------------
+
+void software_list_device::static_set_filter(device_t &device, const char *filter)
+{
+ downcast<software_list_device &>(device).m_filter = filter;
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void software_list_device::device_start()
+{
+}
+
+
+
/***************************************************************************
EXPAT INTERFACES
***************************************************************************/
@@ -1216,7 +1273,7 @@ static int softlist_penalty_compare(const char *source, const char *target)
software_list_find_approx_matches
-------------------------------------------------*/
-void software_list_find_approx_matches(software_list_config *swlistcfg, software_list *swlist, const char *name, int matches, software_info **list, const char* interface)
+void software_list_find_approx_matches(software_list_device *swlistdev, software_list *swlist, const char *name, int matches, software_info **list, const char* interface)
{
#undef rand
@@ -1243,7 +1300,7 @@ void software_list_find_approx_matches(software_list_config *swlistcfg, software
software_info *candidate = swinfo;
software_part *part = software_find_part(swinfo, NULL, NULL);
- if ((interface==NULL || !strcmp(interface, part->interface_)) && (is_software_compatible(part, swlistcfg)))
+ if ((interface==NULL || !strcmp(interface, part->interface_)) && (is_software_compatible(part, swlistdev)))
{
/* pick the best match between driver name and description */
@@ -1442,19 +1499,19 @@ software_part *software_part_next(software_part *part)
software_display_matches
-------------------------------------------------*/
-void software_display_matches(const device_list &devlist,emu_options &options, const char *interface ,const char *name)
+void software_display_matches(const machine_config &config,emu_options &options, const char *interface ,const char *name)
{
// check if there is at least a software list
- if (devlist.first(SOFTWARE_LIST))
+ software_list_device_iterator deviter(config.root_device());
+ if (deviter.first())
{
mame_printf_error("\n\"%s\" approximately matches the following\n"
"supported software items (best match first):\n\n", name);
}
- for (device_t *swlists = devlist.first(SOFTWARE_LIST); swlists != NULL; swlists = swlists->typenext())
+ for (software_list_device *swlist = deviter.first(); swlist != NULL; swlist = deviter.next())
{
- software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(swlists)->inline_config();
- software_list *list = software_list_open(options, swlist->list_name, FALSE, NULL);
+ software_list *list = software_list_open(options, swlist->list_name(), FALSE, NULL);
if (list)
{
@@ -1467,10 +1524,10 @@ void software_display_matches(const device_list &devlist,emu_options &options, c
if (matches[0] != 0)
{
- if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)
- mame_printf_error("* Software list \"%s\" (%s) matches: \n", swlist->list_name, software_list_get_description(list));
+ if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM)
+ mame_printf_error("* Software list \"%s\" (%s) matches: \n", swlist->list_name(), software_list_get_description(list));
else
- mame_printf_error("* Compatible software list \"%s\" (%s) matches: \n", swlist->list_name, software_list_get_description(list));
+ mame_printf_error("* Compatible software list \"%s\" (%s) matches: \n", swlist->list_name(), software_list_get_description(list));
// print them out
for (softnum = 0; softnum < ARRAY_LENGTH(matches); softnum++)
@@ -1484,7 +1541,7 @@ void software_display_matches(const device_list &devlist,emu_options &options, c
}
}
-static void find_software_item(const device_list &devlist, emu_options &options, const device_image_interface *image, const char *path, software_list **software_list_ptr, software_info **software_info_ptr,software_part **software_part_ptr, const char **sw_list_name)
+static void find_software_item(const machine_config &config, emu_options &options, const device_image_interface *image, const char *path, software_list **software_list_ptr, software_info **software_info_ptr,software_part **software_part_ptr, const char **sw_list_name)
{
char *swlist_name, *swname, *swpart; //, *swname_bckp;
*software_list_ptr = NULL;
@@ -1516,33 +1573,28 @@ static void find_software_item(const device_list &devlist, emu_options &options,
else
{
/* Loop through all the software lists named in the driver */
- for (device_t *swlists = devlist.first(SOFTWARE_LIST); swlists != NULL; swlists = swlists->typenext())
+ software_list_device_iterator deviter(config.root_device());
+ for (software_list_device *swlist = deviter.first(); swlist != NULL; swlist = deviter.next())
{
- if ( swlists )
- {
+ const char *swlist_name = swlist->list_name();
- software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(swlists)->inline_config();
+ if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM)
+ {
+ if ( *software_list_ptr )
+ {
+ software_list_close( *software_list_ptr );
+ }
- swlist_name = swlist->list_name;
+ *software_list_ptr = software_list_open( options, swlist_name, FALSE, NULL );
- if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)
+ if ( software_list_ptr )
{
- if ( *software_list_ptr )
- {
- software_list_close( *software_list_ptr );
- }
+ *software_info_ptr = software_list_find( *software_list_ptr, swname, NULL );
- *software_list_ptr = software_list_open( options, swlist_name, FALSE, NULL );
-
- if ( software_list_ptr )
+ if ( *software_info_ptr )
{
- *software_info_ptr = software_list_find( *software_list_ptr, swname, NULL );
-
- if ( *software_info_ptr )
- {
- *software_part_ptr = software_find_part( *software_info_ptr, swpart, interface );
- if (*software_part_ptr) break;
- }
+ *software_part_ptr = software_find_part( *software_info_ptr, swpart, interface );
+ if (*software_part_ptr) break;
}
}
}
@@ -1634,12 +1686,12 @@ bool load_software_part(emu_options &options, device_image_interface *image, con
*sw_info = NULL;
*sw_part = NULL;
- find_software_item(image->device().machine().devicelist(), options, image, path, &software_list_ptr, &software_info_ptr, &software_part_ptr, &swlist_name);
+ find_software_item(image->device().machine().config(), options, image, path, &software_list_ptr, &software_info_ptr, &software_part_ptr, &swlist_name);
// if no match has been found, we suggest similar shortnames
if (software_info_ptr == NULL)
{
- software_display_matches(image->device().machine().devicelist(),image->device().machine().options(), image->image_interface(), path);
+ software_display_matches(image->device().machine().config(),image->device().machine().options(), image->image_interface(), path);
}
if ( software_part_ptr )
@@ -1704,12 +1756,12 @@ bool load_software_part(emu_options &options, device_image_interface *image, con
*full_sw_name = auto_alloc_array( image->device().machine(), char, strlen(swlist_name) + strlen(software_info_ptr->shortname) + strlen(software_part_ptr->name) + 3 );
sprintf( *full_sw_name, "%s:%s:%s", swlist_name, software_info_ptr->shortname, software_part_ptr->name );
- for (device_t *swlists = image->device().machine().devicelist().first(SOFTWARE_LIST); swlists != NULL; swlists = swlists->typenext())
+ software_list_device_iterator iter(image->device().machine().root_device());
+ for (software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next())
{
- software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(swlists)->inline_config();
- if (strcmp(swlist->list_name,swlist_name)==0) {
+ if (strcmp(swlist->list_name(),swlist_name)==0) {
if (!is_software_compatible(software_part_ptr, swlist)) {
- mame_printf_warning("WARNING! the set %s might not work on this system due to missing filter(s) '%s'\n",software_info_ptr->shortname,swlist->filter);
+ mame_printf_warning("WARNING! the set %s might not work on this system due to missing filter(s) '%s'\n",software_info_ptr->shortname,swlist->filter());
}
break;
}
@@ -1723,12 +1775,12 @@ bool load_software_part(emu_options &options, device_image_interface *image, con
software_part *req_software_part_ptr = NULL;
const char *req_swlist_name = NULL;
- find_software_item(image->device().machine().devicelist(), options, NULL, requirement, &req_software_list_ptr, &req_software_info_ptr, &req_software_part_ptr, &req_swlist_name);
+ find_software_item(image->device().machine().config(), options, NULL, requirement, &req_software_list_ptr, &req_software_info_ptr, &req_software_part_ptr, &req_swlist_name);
if ( req_software_list_ptr )
{
- device_image_interface *req_image = NULL;
- for (bool gotone = image->device().machine().devicelist().first(req_image); gotone; gotone = req_image->next(req_image))
+ image_interface_iterator imgiter(image->device().machine().root_device());
+ for (device_image_interface *req_image = imgiter.first(); req_image != NULL; req_image = imgiter.next())
{
const char *interface = req_image->image_interface();
if (interface != NULL)
@@ -1791,7 +1843,7 @@ const char *software_part_get_feature(const software_part *part, const char *fea
software_get_default_slot
-------------------------------------------------*/
- const char *software_get_default_slot(const device_list &devlist, emu_options &options, const device_image_interface *image, const char* default_card_slot)
+ const char *software_get_default_slot(const machine_config &config, emu_options &options, const device_image_interface *image, const char* default_card_slot)
{
const char* retVal = NULL;
const char* path = options.value(image->instance_name());
@@ -1802,7 +1854,7 @@ const char *software_part_get_feature(const software_part *part, const char *fea
if (strlen(path)>0) {
retVal = default_card_slot;
- find_software_item(devlist, options, image, path, &software_list_ptr, &software_info_ptr, &software_part_ptr, &swlist_name);
+ find_software_item(config, options, image, path, &software_list_ptr, &software_info_ptr, &software_part_ptr, &swlist_name);
if (software_part_ptr!=NULL) {
const char *slot = software_part_get_feature(software_part_ptr, "slot");
if (slot!=NULL) {
@@ -1819,10 +1871,10 @@ const char *software_part_get_feature(const software_part *part, const char *fea
is_software_compatible
-------------------------------------------------*/
-bool is_software_compatible(const software_part *swpart, const software_list_config *swlist)
+bool is_software_compatible(const software_part *swpart, const software_list_device *swlist)
{
const char *compatibility = software_part_get_feature(swpart, "compatibility");
- const char *filter = swlist->filter;
+ const char *filter = swlist->filter();
if ((compatibility==NULL) || (filter==NULL)) return TRUE;
astring comp = astring(compatibility,",");
char *filt = core_strdup(filter);
@@ -1856,229 +1908,138 @@ bool swinfo_has_multiple_parts(const software_info *swinfo, const char *interfac
***************************************************************************/
-static DEVICE_START( software_list )
-{
-}
-
void validate_error_proc(const char *message)
{
- mame_printf_error("%s",message);
+ mame_printf_error("%s", message);
}
-void validate_softlists(emu_options &options)
+void software_list_device::device_validity_check(validity_checker &valid) const
{
- driver_enumerator drivlist(options);
- // first determine the maximum number of lists we might encounter
- int list_count = 0;
- while (drivlist.next())
- for (const device_t *dev = drivlist.config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext())
- {
- software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config();
+ // add to the global map whenever we check a list so we don't re-check
+ // it in the future
+ if (s_checked_lists.add(m_list_name, 1, false) == TMERR_DUPLICATE)
+ return;
- if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)
- list_count++;
- }
+ softlist_map names;
+ softlist_map descriptions;
- // allocate a list
- astring *lists = global_alloc_array(astring, list_count);
- bool error = FALSE;
- if (list_count)
+ enum { NAME_LEN_PARENT = 8, NAME_LEN_CLONE = 16 };
+
+ software_list *list = software_list_open(mconfig().options(), m_list_name, FALSE, NULL);
+ if ( list )
{
- drivlist.reset();
- list_count = 0;
- while (drivlist.next())
- for (const device_t *dev = drivlist.config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext())
+ software_list_parse( list, &validate_error_proc, NULL );
+
+ for (software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo))
{
- software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config();
- softlist_map names;
- softlist_map descriptions;
+ const char *s;
+ int is_clone = 0;
- enum { NAME_LEN_PARENT = 8, NAME_LEN_CLONE = 16 };
+ /* First, check if the xml got corrupted: */
- software_list *list = software_list_open(options, swlist->list_name, FALSE, NULL);
- if ( list )
+ /* Did we lost any description? */
+ if (swinfo->longname == NULL)
{
- /* Verify if we have encountered this list before */
- bool seen_before = false;
- for (int seen_index = 0; seen_index < list_count && !seen_before; seen_index++)
- if (lists[seen_index] == swlist->list_name)
- seen_before = true;
+ mame_printf_error("%s: %s has no description\n", list->file->filename(), swinfo->shortname);
+ break;
+ }
- if (!seen_before)
- {
- lists[list_count++] = swlist->list_name;
- software_list_parse( list, &validate_error_proc, NULL );
+ /* Did we lost any year? */
+ if (swinfo->year == NULL)
+ {
+ mame_printf_error("%s: %s has no year\n", list->file->filename(), swinfo->shortname);
+ break;
+ }
- for (software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo))
- {
- const char *s;
- int is_clone = 0;
+ /* Did we lost any publisher? */
+ if (swinfo->publisher == NULL)
+ {
+ mame_printf_error("%s: %s has no publisher\n", list->file->filename(), swinfo->shortname);
+ break;
+ }
- /* First, check if the xml got corrupted: */
+ /* Second, since the xml is fine, run additional checks: */
- /* Did we lost any description? */
- if (swinfo->longname == NULL)
- {
- mame_printf_error("%s: %s has no description\n", list->file->filename(), swinfo->shortname);
- error = TRUE; break;
- }
+ /* check for duplicate names */
+ if (names.add(swinfo->shortname, swinfo, FALSE) == TMERR_DUPLICATE)
+ {
+ software_info *match = names.find(swinfo->shortname);
+ mame_printf_error("%s: %s is a duplicate name (%s)\n", list->file->filename(), swinfo->shortname, match->shortname);
+ }
- /* Did we lost any year? */
- if (swinfo->year == NULL)
- {
- mame_printf_error("%s: %s has no year\n", list->file->filename(), swinfo->shortname);
- error = TRUE; break;
- }
+ /* check for duplicate descriptions */
+ if (descriptions.add(astring(swinfo->longname).makelower().cstr(), swinfo, FALSE) == TMERR_DUPLICATE)
+ mame_printf_error("%s: %s is a duplicate description (%s)\n", list->file->filename(), swinfo->longname, swinfo->shortname);
- /* Did we lost any publisher? */
- if (swinfo->publisher == NULL)
- {
- mame_printf_error("%s: %s has no publisher\n", list->file->filename(), swinfo->shortname);
- error = TRUE; break;
- }
+ if (swinfo->parentname != NULL)
+ {
+ is_clone = 1;
- /* Second, since the xml is fine, run additional checks: */
+ if (strcmp(swinfo->parentname, swinfo->shortname) == 0)
+ {
+ mame_printf_error("%s: %s is set as a clone of itself\n", list->file->filename(), swinfo->shortname);
+ break;
+ }
- /* check for duplicate names */
- if (names.add(swinfo->shortname, swinfo, FALSE) == TMERR_DUPLICATE)
- {
- software_info *match = names.find(swinfo->shortname);
- mame_printf_error("%s: %s is a duplicate name (%s)\n", list->file->filename(), swinfo->shortname, match->shortname);
- error = TRUE;
- }
+ /* make sure the parent exists */
+ software_info *swinfo2 = software_list_find(list, swinfo->parentname, NULL );
- /* check for duplicate descriptions */
- if (descriptions.add(astring(swinfo->longname).makelower().cstr(), swinfo, FALSE) == TMERR_DUPLICATE)
- {
- mame_printf_error("%s: %s is a duplicate description (%s)\n", list->file->filename(), swinfo->longname, swinfo->shortname);
- error = TRUE;
- }
+ if (!swinfo2)
+ mame_printf_error("%s: parent '%s' software for '%s' not found\n", list->file->filename(), swinfo->parentname, swinfo->shortname);
+ else if (swinfo2->parentname != NULL)
+ mame_printf_error("%s: %s is a clone of a clone\n", list->file->filename(), swinfo->shortname);
+ }
- if (swinfo->parentname != NULL)
- {
- is_clone = 1;
+ /* make sure the driver name is 8 chars or less */
+ if ((is_clone && strlen(swinfo->shortname) > NAME_LEN_CLONE) || ((!is_clone) && strlen(swinfo->shortname) > NAME_LEN_PARENT))
+ mame_printf_error("%s: %s %s driver name must be %d characters or less\n", list->file->filename(), swinfo->shortname,
+ is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT);
- if (strcmp(swinfo->parentname, swinfo->shortname) == 0)
- {
- mame_printf_error("%s: %s is set as a clone of itself\n", list->file->filename(), swinfo->shortname);
- error = TRUE;
- break;
- }
+ /* make sure the year is only digits, '?' or '+' */
+ for (s = swinfo->year; *s; s++)
+ if (!isdigit((UINT8)*s) && *s != '?' && *s != '+')
+ {
+ mame_printf_error("%s: %s has an invalid year '%s'\n", list->file->filename(), swinfo->shortname, swinfo->year);
+ break;
+ }
- /* make sure the parent exists */
- software_info *swinfo2 = software_list_find(list, swinfo->parentname, NULL );
+ softlist_map part_names;
- if (!swinfo2)
- {
- mame_printf_error("%s: parent '%s' software for '%s' not found\n", list->file->filename(), swinfo->parentname, swinfo->shortname);
- error = TRUE;
- }
- else
- {
- if (swinfo2->parentname != NULL)
- {
- mame_printf_error("%s: %s is a clone of a clone\n", list->file->filename(), swinfo->shortname);
- error = TRUE;
- }
- }
- }
-
- /* make sure the driver name is 8 chars or less */
- if ((is_clone && strlen(swinfo->shortname) > NAME_LEN_CLONE) || ((!is_clone) && strlen(swinfo->shortname) > NAME_LEN_PARENT))
- {
- mame_printf_error("%s: %s %s driver name must be %d characters or less\n", list->file->filename(), swinfo->shortname,
- is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT);
- error = TRUE;
- }
+ for (software_part *swpart = software_find_part(swinfo, NULL, NULL); swpart != NULL; swpart = software_part_next(swpart))
+ {
+ if (swpart->interface_ == NULL)
+ mame_printf_error("%s: %s has a part (%s) without interface\n", list->file->filename(), swinfo->shortname, swpart->name);
- /* make sure the year is only digits, '?' or '+' */
- for (s = swinfo->year; *s; s++)
- if (!isdigit((UINT8)*s) && *s != '?' && *s != '+')
- {
- mame_printf_error("%s: %s has an invalid year '%s'\n", list->file->filename(), swinfo->shortname, swinfo->year);
- error = TRUE;
- break;
- }
+ if (software_find_romdata(swpart, NULL) == NULL)
+ mame_printf_error("%s: %s has a part (%s) with no data\n", list->file->filename(), swinfo->shortname, swpart->name);
- softlist_map part_names;
+ if (part_names.add(swpart->name, swinfo, FALSE) == TMERR_DUPLICATE)
+ mame_printf_error("%s: %s has a part (%s) whose name is duplicate\n", list->file->filename(), swinfo->shortname, swpart->name);
- for (software_part *swpart = software_find_part(swinfo, NULL, NULL); swpart != NULL; swpart = software_part_next(swpart))
- {
- if (swpart->interface_ == NULL)
- {
- mame_printf_error("%s: %s has a part (%s) without interface\n", list->file->filename(), swinfo->shortname, swpart->name);
- error = TRUE;
- }
+ for (struct rom_entry *swdata = software_find_romdata(swpart, NULL); swdata != NULL; swdata = software_romdata_next(swdata))
+ {
+ struct rom_entry *data = swdata;
- if (software_find_romdata(swpart, NULL) == NULL)
- {
- mame_printf_error("%s: %s has a part (%s) with no data\n", list->file->filename(), swinfo->shortname, swpart->name);
- error = TRUE;
- }
+ if (data->_name && data->_hashdata)
+ {
+ const char *str;
- if (part_names.add(swpart->name, swinfo, FALSE) == TMERR_DUPLICATE)
+ /* make sure it's all lowercase */
+ for (str = data->_name; *str; str++)
+ if (tolower((UINT8)*str) != *str)
{
- mame_printf_error("%s: %s has a part (%s) whose name is duplicate\n", list->file->filename(), swinfo->shortname, swpart->name);
- error = TRUE;
+ mame_printf_error("%s: %s has upper case ROM name %s\n", list->file->filename(), swinfo->shortname, data->_name);
+ break;
}
- for (struct rom_entry *swdata = software_find_romdata(swpart, NULL); swdata != NULL; swdata = software_romdata_next(swdata))
- {
- struct rom_entry *data = swdata;
-
- if (data->_name && data->_hashdata)
- {
- const char *str;
-
- /* make sure it's all lowercase */
- for (str = data->_name; *str; str++)
- if (tolower((UINT8)*str) != *str)
- {
- mame_printf_error("%s: %s has upper case ROM name %s\n", list->file->filename(), swinfo->shortname, data->_name);
- error = TRUE;
- break;
- }
-
- /* make sure the hash is valid */
- hash_collection hashes;
- if (!hashes.from_internal_string(data->_hashdata))
- {
- mame_printf_error("%s: %s has rom '%s' with an invalid hash string '%s'\n", list->file->filename(), swinfo->shortname, data->_name, data->_hashdata);
- error = TRUE;
- }
- }
- }
- }
+ /* make sure the hash is valid */
+ hash_collection hashes;
+ if (!hashes.from_internal_string(data->_hashdata))
+ mame_printf_error("%s: %s has rom '%s' with an invalid hash string '%s'\n", list->file->filename(), swinfo->shortname, data->_name, data->_hashdata);
}
}
- software_list_close(list);
}
}
+ software_list_close(list);
}
- if (error)
- throw emu_fatalerror(MAMERR_FAILED_VALIDITY, "Validity checks failed");
}
-
-DEVICE_GET_INFO( software_list )
-{
- switch (state)
- {
- /* --- the following bits of info are returned as 64-bit signed integers --- */
- case DEVINFO_INT_TOKEN_BYTES: info->i = 1; break;
- case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(software_list_config); break;
-
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( software_list ); break;
- case DEVINFO_FCT_STOP: /* Nothing */ break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case DEVINFO_STR_NAME: strcpy(info->s, "Software lists"); break;
- case DEVINFO_STR_FAMILY: strcpy(info->s, "Software lists"); break;
- case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
- case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
- case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright MESS Team"); break;
- }
-}
-
-
-DEFINE_LEGACY_DEVICE(SOFTWARE_LIST, software_list);
diff --git a/src/emu/softlist.h b/src/emu/softlist.h
index 9983bcc68d6..6c8b5af041e 100644
--- a/src/emu/softlist.h
+++ b/src/emu/softlist.h
@@ -14,6 +14,84 @@
#include "pool.h"
+
+#define SOFTWARE_SUPPORTED_YES 0
+#define SOFTWARE_SUPPORTED_PARTIAL 1
+#define SOFTWARE_SUPPORTED_NO 2
+
+enum softlist_type
+{
+ SOFTWARE_LIST_ORIGINAL_SYSTEM,
+ SOFTWARE_LIST_COMPATIBLE_SYSTEM
+};
+
+#define MCFG_SOFTWARE_LIST_CONFIG(_list,_list_type) \
+ software_list_device::static_set_config(*device, _list, _list_type);
+
+#define MCFG_SOFTWARE_LIST_ADD( _tag, _list ) \
+ MCFG_DEVICE_ADD( _tag, SOFTWARE_LIST, 0 ) \
+ MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_ORIGINAL_SYSTEM)
+
+#define MCFG_SOFTWARE_LIST_COMPATIBLE_ADD( _tag, _list ) \
+ MCFG_DEVICE_ADD( _tag, SOFTWARE_LIST, 0 ) \
+ MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_COMPATIBLE_SYSTEM)
+
+#define MCFG_SOFTWARE_LIST_MODIFY( _tag, _list ) \
+ MCFG_DEVICE_MODIFY( _tag ) \
+ MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_ORIGINAL_SYSTEM)
+
+#define MCFG_SOFTWARE_LIST_COMPATIBLE_MODIFY( _tag, _list ) \
+ MCFG_DEVICE_MODIFY( _tag ) \
+ MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_COMPATIBLE_SYSTEM)
+
+#define MCFG_SOFTWARE_LIST_FILTER( _tag, _filter ) \
+ MCFG_DEVICE_MODIFY( _tag ) \
+ software_list_device::static_set_filter(*device, _filter);
+
+
+// ======================> software_list_device
+
+class software_list_device : public device_t
+{
+public:
+ // construction/destruction
+ software_list_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // inline configuration helpers
+ static void static_set_config(device_t &device, const char *list, softlist_type list_type);
+ static void static_set_filter(device_t &device, const char *filter);
+
+ // getters
+ const char *list_name() const { return m_list_name; }
+ softlist_type list_type() const { return m_list_type; }
+ const char *filter() const { return m_filter; }
+
+ // validation helpers
+ static void reset_checked_lists() { s_checked_lists.reset(); }
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_validity_check(validity_checker &valid) const ATTR_COLD;
+
+ // configuration state
+ const char * m_list_name;
+ softlist_type m_list_type;
+ const char * m_filter;
+
+ // static state
+ static tagmap_t<UINT8> s_checked_lists;
+};
+
+
+// device type definition
+extern const device_type SOFTWARE_LIST;
+
+// device type iterator
+typedef device_type_iterator<&device_creator<software_list_device>, software_list_device> software_list_device_iterator;
+
+
+
/*********************************************************************
Internal structures and XML file handling
@@ -95,13 +173,6 @@ struct software_list
int list_entries;
};
-struct software_list_config
-{
- char *list_name;
- UINT32 list_type;
- const char *filter;
-};
-
/* Handling a software list */
software_list *software_list_open(emu_options &options, const char *listname, int is_preload, void (*error_proc)(const char *message));
void software_list_close(const software_list *swlist);
@@ -123,53 +194,11 @@ const char *software_part_get_feature(const software_part *part, const char *fea
bool load_software_part(emu_options &options, device_image_interface *image, const char *path, software_info **sw_info, software_part **sw_part, char **full_sw_name);
-void software_display_matches(const device_list &devlist, emu_options &options,const char *interface,const char *swname_bckp);
+void software_display_matches(const machine_config &config, emu_options &options,const char *interface,const char *swname_bckp);
-const char *software_get_default_slot(const device_list &devlist, emu_options &options, const device_image_interface *image, const char* default_card_slot);
+const char *software_get_default_slot(const machine_config &config, emu_options &options, const device_image_interface *image, const char* default_card_slot);
-void validate_softlists(emu_options &options);
-
-bool is_software_compatible(const software_part *swpart, const software_list_config *swlist);
+bool is_software_compatible(const software_part *swpart, const software_list_device *swlist);
bool swinfo_has_multiple_parts(const software_info *swinfo, const char *interface);
-/*********************************************************************
-
- Driver software list configuration
-
-*********************************************************************/
-DECLARE_LEGACY_DEVICE(SOFTWARE_LIST, software_list);
-
-#define SOFTWARE_SUPPORTED_YES 0
-#define SOFTWARE_SUPPORTED_PARTIAL 1
-#define SOFTWARE_SUPPORTED_NO 2
-
-#define SOFTWARE_LIST_ORIGINAL_SYSTEM 0
-#define SOFTWARE_LIST_COMPATIBLE_SYSTEM 1
-
-#define MCFG_SOFTWARE_LIST_CONFIG(_list,_list_type) \
- MCFG_DEVICE_CONFIG_DATAPTR(software_list_config, list_name, _list) \
- MCFG_DEVICE_CONFIG_DATA32(software_list_config, list_type, _list_type)
-
-#define MCFG_SOFTWARE_LIST_ADD( _tag, _list ) \
- MCFG_DEVICE_ADD( _tag, SOFTWARE_LIST, 0 ) \
- MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_ORIGINAL_SYSTEM)
-
-
-#define MCFG_SOFTWARE_LIST_COMPATIBLE_ADD( _tag, _list ) \
- MCFG_DEVICE_ADD( _tag, SOFTWARE_LIST, 0 ) \
- MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_COMPATIBLE_SYSTEM)
-
-
-#define MCFG_SOFTWARE_LIST_MODIFY( _tag, _list ) \
- MCFG_DEVICE_MODIFY( _tag ) \
- MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_ORIGINAL_SYSTEM)
-
-#define MCFG_SOFTWARE_LIST_COMPATIBLE_MODIFY( _tag, _list ) \
- MCFG_DEVICE_MODIFY( _tag ) \
- MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_COMPATIBLE_SYSTEM)
-
-#define MCFG_SOFTWARE_LIST_FILTER( _tag, _filter ) \
- MCFG_DEVICE_MODIFY( _tag ) \
- MCFG_DEVICE_CONFIG_DATAPTR(software_list_config, filter, _filter)
-
#endif
diff --git a/src/emu/sound.c b/src/emu/sound.c
index 0586b6a72e8..eb201a7448f 100644
--- a/src/emu/sound.c
+++ b/src/emu/sound.c
@@ -788,7 +788,10 @@ sound_manager::sound_manager(running_machine &machine)
machine.m_sample_rate = 11025;
// count the speakers
- VPRINTF(("total speakers = %d\n", machine.devicelist().count(SPEAKER)));
+#if VERBOSE
+ speaker_device_iterator iter(machine.root_device());
+ VPRINTF(("total speakers = %d\n", iter.count()));
+#endif
// allocate memory for mix buffers
m_leftmix = auto_alloc_array(machine, INT32, machine.sample_rate());
@@ -862,7 +865,8 @@ void sound_manager::set_attenuation(int attenuation)
bool sound_manager::indexed_speaker_input(int index, speaker_input &info) const
{
// scan through the speakers until we find the indexed input
- for (info.speaker = downcast<speaker_device *>(machine().devicelist().first(SPEAKER)); info.speaker != NULL; info.speaker = info.speaker->next_speaker())
+ speaker_device_iterator iter(machine().root_device());
+ for (info.speaker = iter.first(); info.speaker != NULL; info.speaker = iter.next())
{
if (index < info.speaker->inputs())
{
@@ -899,8 +903,8 @@ void sound_manager::mute(bool mute, UINT8 reason)
void sound_manager::reset()
{
// reset all the sound chips
- device_sound_interface *sound = NULL;
- for (bool gotone = machine().devicelist().first(sound); gotone; gotone = sound->next(sound))
+ sound_interface_iterator iter(machine().root_device());
+ for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next())
sound->device().reset();
}
@@ -1003,7 +1007,8 @@ void sound_manager::update()
// force all the speaker streams to generate the proper number of samples
int samples_this_update = 0;
- for (speaker_device *speaker = downcast<speaker_device *>(machine().devicelist().first(SPEAKER)); speaker != NULL; speaker = speaker->next_speaker())
+ speaker_device_iterator iter(machine().root_device());
+ for (speaker_device *speaker = iter.first(); speaker != NULL; speaker = iter.next())
speaker->mix(m_leftmix, m_rightmix, samples_this_update, (m_muted & MUTE_REASON_SYSTEM));
// now downmix the final result
diff --git a/src/emu/sound/bsmt2000.c b/src/emu/sound/bsmt2000.c
index 4f3ddbf930a..20d9269cb85 100644
--- a/src/emu/sound/bsmt2000.c
+++ b/src/emu/sound/bsmt2000.c
@@ -173,7 +173,7 @@ machine_config_constructor bsmt2000_device::device_mconfig_additions() const
void bsmt2000_device::device_start()
{
// find our CPU
- m_cpu = downcast<tms32015_device*>(subdevice("bsmt2000"));
+ m_cpu = subdevice<tms32015_device>("bsmt2000");
// find our direct access
m_direct = &space()->direct();
diff --git a/src/emu/sound/cdda.c b/src/emu/sound/cdda.c
index 6eea9e498fb..8b4a9af1118 100644
--- a/src/emu/sound/cdda.c
+++ b/src/emu/sound/cdda.c
@@ -90,9 +90,8 @@ void cdda_set_cdrom(device_t *device, void *file)
device_t *cdda_from_cdrom(running_machine &machine, void *file)
{
- device_sound_interface *sound = NULL;
-
- for (bool gotone = machine.devicelist().first(sound); gotone; gotone = sound->next(sound))
+ sound_interface_iterator iter(machine.root_device());
+ for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next())
if (sound->device().type() == CDDA)
{
cdda_info *info = get_safe_token(*sound);
diff --git a/src/emu/sound/disc_inp.c b/src/emu/sound/disc_inp.c
index d2e09bcd7e0..e30a9af4340 100644
--- a/src/emu/sound/disc_inp.c
+++ b/src/emu/sound/disc_inp.c
@@ -75,7 +75,8 @@ DISCRETE_RESET(dss_adjustment)
{
double min, max;
- m_port = m_device->machine().m_portlist.find((const char *)this->custom_data());
+ astring fulltag;
+ m_port = m_device->machine().m_portlist.find(m_device->siblingtag(fulltag, (const char *)this->custom_data()).cstr());
if (m_port == NULL)
fatalerror("DISCRETE_ADJUSTMENT - NODE_%d has invalid tag", this->index());
diff --git a/src/emu/sound/samples.h b/src/emu/sound/samples.h
index 0d44d994c2f..b3abd505b04 100644
--- a/src/emu/sound/samples.h
+++ b/src/emu/sound/samples.h
@@ -46,4 +46,6 @@ loaded_samples *readsamples(running_machine &machine, const char *const *samplen
DECLARE_LEGACY_SOUND_DEVICE(SAMPLES, samples);
+typedef device_type_iterator<&legacy_device_creator<samples_device>, samples_device> samples_device_iterator;
+
#endif /* __SAMPLES_H__ */
diff --git a/src/emu/sound/wave.c b/src/emu/sound/wave.c
index 179b02512e6..1d879de288b 100644
--- a/src/emu/sound/wave.c
+++ b/src/emu/sound/wave.c
@@ -22,7 +22,6 @@
static STREAM_UPDATE( wave_sound_update )
{
cassette_image_device *cass = (cassette_image_device *)param;
- int speakers = cass->machine().devicelist().count(SPEAKER);
cassette_image *cassette;
cassette_state state;
double time_index;
@@ -31,6 +30,8 @@ static STREAM_UPDATE( wave_sound_update )
stream_sample_t *right_buffer = NULL;
int i;
+ speaker_device_iterator spkiter(cass->machine().root_device());
+ int speakers = spkiter.count();
if (speakers>1)
right_buffer = outputs[1];
@@ -71,7 +72,8 @@ static DEVICE_START( wave )
assert( device != NULL );
assert( device->static_config() != NULL );
- int speakers = device->machine().config().devicelist().count(SPEAKER);
+ speaker_device_iterator spkiter(device->machine().root_device());
+ int speakers = spkiter.count();
image = dynamic_cast<cassette_image_device *>(device->machine().device( (const char *)device->static_config()));
if (speakers > 1)
device->machine().sound().stream_alloc(*device, 0, 2, device->machine().sample_rate(), (void *)image, wave_sound_update);
diff --git a/src/emu/speaker.h b/src/emu/speaker.h
index 31b6f4696c7..3ead6eab11c 100644
--- a/src/emu/speaker.h
+++ b/src/emu/speaker.h
@@ -84,9 +84,6 @@ public:
// inline configuration helpers
static void static_set_position(device_t &device, double x, double y, double z);
- // getters
- speaker_device *next_speaker() const { return downcast<speaker_device *>(typenext()); }
-
// internally for use by the sound system
void mix(INT32 *leftmix, INT32 *rightmix, int &samples_this_update, bool suppress);
@@ -117,4 +114,8 @@ protected:
extern const device_type SPEAKER;
+// speaker device iterator
+typedef device_type_iterator<&device_creator<speaker_device>, speaker_device> speaker_device_iterator;
+
+
#endif /* __SOUND_H__ */
diff --git a/src/emu/timer.c b/src/emu/timer.c
index 28ed940c93b..70a81315b6a 100644
--- a/src/emu/timer.c
+++ b/src/emu/timer.c
@@ -176,54 +176,40 @@ void timer_device::static_set_ptr(device_t &device, void *ptr)
// configuration
//-------------------------------------------------
-bool timer_device::device_validity_check(emu_options &options, const game_driver &driver) const
+void timer_device::device_validity_check(validity_checker &valid) const
{
- bool error = false;
-
// type based configuration
switch (m_type)
{
case TIMER_TYPE_GENERIC:
if (m_screen_tag != NULL || m_first_vpos != 0 || m_start_delay != attotime::zero)
- mame_printf_warning("%s: %s generic timer '%s' specified parameters for a scanline timer\n", driver.source_file, driver.name, tag());
+ mame_printf_warning("Generic timer specified parameters for a scanline timer\n");
if (m_period != attotime::zero || m_start_delay != attotime::zero)
- mame_printf_warning("%s: %s generic timer '%s' specified parameters for a periodic timer\n", driver.source_file, driver.name, tag());
+ mame_printf_warning("Generic timer specified parameters for a periodic timer\n");
break;
case TIMER_TYPE_PERIODIC:
if (m_screen_tag != NULL || m_first_vpos != 0)
- mame_printf_warning("%s: %s periodic timer '%s' specified parameters for a scanline timer\n", driver.source_file, driver.name, tag());
+ mame_printf_warning("Periodic timer specified parameters for a scanline timer\n");
if (m_period <= attotime::zero)
- {
- mame_printf_error("%s: %s periodic timer '%s' specified invalid period\n", driver.source_file, driver.name, tag());
- error = true;
- }
+ mame_printf_error("Periodic timer specified invalid period\n");
break;
case TIMER_TYPE_SCANLINE:
if (m_period != attotime::zero || m_start_delay != attotime::zero)
- mame_printf_warning("%s: %s scanline timer '%s' specified parameters for a periodic timer\n", driver.source_file, driver.name, tag());
+ mame_printf_warning("Scanline timer specified parameters for a periodic timer\n");
if (m_param != 0)
- mame_printf_warning("%s: %s scanline timer '%s' specified parameter which is ignored\n", driver.source_file, driver.name, tag());
+ mame_printf_warning("Scanline timer specified parameter which is ignored\n");
if (m_first_vpos < 0)
- {
- mame_printf_error("%s: %s scanline timer '%s' specified invalid initial position\n", driver.source_file, driver.name, tag());
- error = true;
- }
+ mame_printf_error("Scanline timer specified invalid initial position\n");
if (m_increment < 0)
- {
- mame_printf_error("%s: %s scanline timer '%s' specified invalid increment\n", driver.source_file, driver.name, tag());
- error = true;
- }
+ mame_printf_error("Scanline timer specified invalid increment\n");
break;
default:
- mame_printf_error("%s: %s timer '%s' has an invalid type\n", driver.source_file, driver.name, tag());
- error = true;
+ mame_printf_error("Invalid type specified\n");
break;
}
-
- return error;
}
diff --git a/src/emu/timer.h b/src/emu/timer.h
index fff33be5ad4..7c01feb0375 100644
--- a/src/emu/timer.h
+++ b/src/emu/timer.h
@@ -142,7 +142,7 @@ public:
private:
// device-level overrides
- virtual bool device_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
diff --git a/src/emu/ui.c b/src/emu/ui.c
index bdea3a453d2..eb87b3cf5ae 100644
--- a/src/emu/ui.c
+++ b/src/emu/ui.c
@@ -1018,29 +1018,30 @@ static astring &warnings_string(running_machine &machine, astring &string)
astring &game_info_astring(running_machine &machine, astring &string)
{
- int scrcount = machine.devicelist().count(SCREEN);
+ screen_device_iterator scriter(machine.root_device());
+ int scrcount = scriter.count();
int found_sound = FALSE;
/* print description, manufacturer, and CPU: */
string.printf("%s\n%s %s\n\nCPU:\n", machine.system().description, machine.system().year, machine.system().manufacturer);
/* loop over all CPUs */
- device_execute_interface *exec = NULL;
- for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec))
+ execute_interface_iterator execiter(machine.root_device());
+ for (device_execute_interface *exec = execiter.first(); exec != NULL; exec = execiter.next())
{
/* get cpu specific clock that takes internal multiplier/dividers into account */
int clock = exec->device().clock();
/* count how many identical CPUs we have */
int count = 1;
- device_execute_interface *scan = NULL;
- for (bool gotanother = exec->next(scan); gotanother; gotanother = scan->next(scan))
+ for (device_execute_interface *scan = execiter.next(); scan != NULL; scan = execiter.next())
{
if (exec->device().type() != scan->device().type() || exec->device().clock() != scan->device().clock())
break;
count++;
exec = scan;
}
+ execiter.set_current(*exec);
/* if more than one, prepend a #x in front of the CPU name */
if (count > 1)
@@ -1055,8 +1056,8 @@ astring &game_info_astring(running_machine &machine, astring &string)
}
/* loop over all sound chips */
- device_sound_interface *sound = NULL;
- for (bool gotone = machine.devicelist().first(sound); gotone; gotone = sound->next(sound))
+ sound_interface_iterator snditer(machine.root_device());
+ for (device_sound_interface *sound = snditer.first(); sound != NULL; sound = snditer.next())
{
/* append the Sound: string */
if (!found_sound)
@@ -1065,14 +1066,14 @@ astring &game_info_astring(running_machine &machine, astring &string)
/* count how many identical sound chips we have */
int count = 1;
- device_sound_interface *scan = NULL;
- for (bool gotanother = sound->next(scan); gotanother; gotanother = scan->next(scan))
+ for (device_sound_interface *scan = snditer.next(); scan != NULL; scan = snditer.next())
{
if (sound->device().type() != scan->device().type() || sound->device().clock() != scan->device().clock())
break;
count++;
sound = scan;
}
+ snditer.set_current(*sound);
/* if more than one, prepend a #x in front of the CPU name */
if (count > 1)
@@ -1095,7 +1096,8 @@ astring &game_info_astring(running_machine &machine, astring &string)
string.cat("None\n");
else
{
- for (screen_device *screen = machine.first_screen(); screen != NULL; screen = screen->next_screen())
+ screen_device_iterator iter(machine.root_device());
+ for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next())
{
if (scrcount > 1)
{
@@ -1271,17 +1273,13 @@ void ui_paste(running_machine &machine)
void ui_image_handler_ingame(running_machine &machine)
{
- device_image_interface *image = NULL;
-
/* run display routine for devices */
if (machine.phase() == MACHINE_PHASE_RUNNING)
{
- for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image))
- {
+ image_interface_iterator iter(machine.root_device());
+ for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
image->call_display();
- }
}
-
}
/*-------------------------------------------------
@@ -1644,7 +1642,6 @@ static slider_state *slider_init(running_machine &machine)
{
input_field_config *field;
input_port_config *port;
- device_t *device;
slider_state *listhead = NULL;
slider_state **tailptr = &listhead;
astring string;
@@ -1683,8 +1680,8 @@ static slider_state *slider_init(running_machine &machine)
/* add CPU overclocking (cheat only) */
if (machine.options().cheat())
{
- device_execute_interface *exec = NULL;
- for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec))
+ execute_interface_iterator iter(machine.root_device());
+ for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next())
{
void *param = (void *)&exec->device();
string.printf("Overclock CPU %s", exec->device().tag());
@@ -1694,7 +1691,8 @@ static slider_state *slider_init(running_machine &machine)
}
/* add screen parameters */
- for (screen_device *screen = machine.first_screen(); screen != NULL; screen = screen->next_screen())
+ screen_device_iterator scriter(machine.root_device());
+ for (screen_device *screen = scriter.first(); screen != NULL; screen = scriter.next())
{
int defxscale = floor(screen->xscale() * 1000.0f + 0.5f);
int defyscale = floor(screen->yscale() * 1000.0f + 0.5f);
@@ -1736,10 +1734,9 @@ static slider_state *slider_init(running_machine &machine)
tailptr = &(*tailptr)->next;
}
- for (device = machine.devicelist().first(); device != NULL; device = device->next())
- {
- laserdisc_device *laserdisc = dynamic_cast<laserdisc_device *>(device);
- if (laserdisc != NULL && laserdisc->overlay_configured())
+ laserdisc_device_iterator lditer(machine.root_device());
+ for (laserdisc_device *laserdisc = lditer.first(); laserdisc != NULL; laserdisc = lditer.next())
+ if (laserdisc->overlay_configured())
{
laserdisc_overlay_config config;
laserdisc->get_overlay_config(config);
@@ -1763,9 +1760,8 @@ static slider_state *slider_init(running_machine &machine)
*tailptr = slider_alloc(machine, string, -500, defyoffset, 500, 2, slider_overyoffset, param);
tailptr = &(*tailptr)->next;
}
- }
- for (screen_device *screen = machine.first_screen(); screen != NULL; screen = screen->next_screen())
+ for (screen_device *screen = scriter.first(); screen != NULL; screen = scriter.next())
if (screen->screen_type() == SCREEN_TYPE_VECTOR)
{
/* add flicker control */
@@ -2172,7 +2168,8 @@ static INT32 slider_beam(running_machine &machine, void *arg, astring *string, I
static char *slider_get_screen_desc(screen_device &screen)
{
- int scrcount = screen.machine().devicelist().count(SCREEN);
+ screen_device_iterator iter(screen.machine().root_device());
+ int scrcount = iter.count();
static char descbuf[256];
if (scrcount > 1)
diff --git a/src/emu/uiimage.c b/src/emu/uiimage.c
index aaedc71c1e5..db1ad578bdf 100644
--- a/src/emu/uiimage.c
+++ b/src/emu/uiimage.c
@@ -770,11 +770,11 @@ ui_menu_file_manager::ui_menu_file_manager(running_machine &machine, render_cont
void ui_menu_file_manager::populate()
{
char buffer[2048];
- device_image_interface *image = NULL;
astring tmp_name;
/* cycle through all devices for this system */
- for (bool gotone = machine().devicelist().first(image); gotone; gotone = image->next(image))
+ image_interface_iterator iter(machine().root_device());
+ for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
{
/* get the image type/id */
snprintf(buffer, ARRAY_LENGTH(buffer),
@@ -1000,15 +1000,8 @@ ui_menu_mess_bitbanger_control::~ui_menu_mess_bitbanger_control()
int ui_menu_mess_tape_control::cassette_count()
{
- int count = 0;
- device_t *device = machine().devicelist().first(CASSETTE);
-
- while ( device )
- {
- count++;
- device = device->typenext();
- }
- return count;
+ cassette_device_iterator iter(machine().root_device());
+ return iter.count();
}
/*-------------------------------------------------
@@ -1018,15 +1011,8 @@ int ui_menu_mess_tape_control::cassette_count()
int ui_menu_mess_bitbanger_control::bitbanger_count()
{
- int count = 0;
- device_t *device = machine().devicelist().first(BITBANGER);
-
- while ( device )
- {
- count++;
- device = device->typenext();
- }
- return count;
+ bitbanger_device_iterator iter(machine().root_device());
+ return iter.count();
}
/*-------------------------------------------------
@@ -1197,14 +1183,8 @@ void ui_menu_mess_tape_control::handle()
/* do we have to load the device? */
if (device == NULL)
{
- int cindex = index;
- for (bool gotone = machine().devicelist().first(device); gotone; gotone = device->next(device))
- {
- if(device->device().type() == CASSETTE) {
- if (cindex==0) break;
- cindex--;
- }
- }
+ cassette_device_iterator iter(machine().root_device());
+ device = iter.byindex(index);
reset((ui_menu_reset_options)0);
}
@@ -1286,14 +1266,8 @@ void ui_menu_mess_bitbanger_control::handle()
/* do we have to load the device? */
if (device == NULL)
{
- int cindex = index;
- for (bool gotone = machine().devicelist().first(device); gotone; gotone = device->next(device))
- {
- if(device->device().type() == BITBANGER) {
- if (cindex==0) break;
- cindex--;
- }
- }
+ bitbanger_device_iterator iter(machine().root_device());
+ device = iter.byindex(index);
reset((ui_menu_reset_options)0);
}
diff --git a/src/emu/uimain.c b/src/emu/uimain.c
index d0e657533c1..fbbead0fa13 100644
--- a/src/emu/uimain.c
+++ b/src/emu/uimain.c
@@ -149,8 +149,8 @@ void ui_menu_main::populate()
menu_text.printf("%s Information",emulator_info::get_capstartgamenoun());
item_append(menu_text.cstr(), NULL, 0, (void *)GAME_INFO);
- device_image_interface *image = NULL;
- if (machine().devicelist().first(image))
+ image_interface_iterator imgiter(machine().root_device());
+ if (imgiter.first() != NULL)
{
/* add image info menu */
item_append("Image Information", NULL, 0, (void *)IMAGE_MENU_IMAGE_INFO);
@@ -159,23 +159,25 @@ void ui_menu_main::populate()
item_append("File Manager", NULL, 0, (void *)IMAGE_MENU_FILE_MANAGER);
/* add tape control menu */
- if (machine().devicelist().first(CASSETTE))
+ cassette_device_iterator cassiter(machine().root_device());
+ if (cassiter.first() != NULL)
item_append("Tape Control", NULL, 0, (void *)MESS_MENU_TAPE_CONTROL);
/* add bitbanger control menu */
- if (machine().devicelist().first(BITBANGER))
+ bitbanger_device_iterator bititer(machine().root_device());
+ if (bititer.first() != NULL)
item_append("Bitbanger Control", NULL, 0, (void *)MESS_MENU_BITBANGER_CONTROL);
}
- device_slot_interface *slot = NULL;
- if (machine().devicelist().first(slot))
+ slot_interface_iterator slotiter(machine().root_device());
+ if (slotiter.first() != NULL)
{
/* add image info menu */
item_append("Slot Devices", NULL, 0, (void *)SLOT_DEVICES);
}
- device_network_interface *network = NULL;
- if (machine().devicelist().first(network))
+ network_interface_iterator netiter(machine().root_device());
+ if (netiter.first() != NULL)
{
/* add image info menu */
item_append("Network Devices", NULL, 0, (void*)NETWORK_DEVICES);
@@ -427,10 +429,9 @@ ui_menu_slot_devices::ui_menu_slot_devices(running_machine &machine, render_cont
void ui_menu_slot_devices::populate()
{
- device_slot_interface *slot = NULL;
-
/* cycle through all devices for this system */
- for (bool gotone = machine().devicelist().first(slot); gotone; gotone = slot->next(slot))
+ slot_interface_iterator iter(machine().root_device());
+ for (device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next())
{
/* record the menu item */
const char *title = get_slot_device(slot);
@@ -481,10 +482,9 @@ ui_menu_network_devices::~ui_menu_network_devices()
void ui_menu_network_devices::populate()
{
- device_network_interface *network = NULL;
-
/* cycle through all devices for this system */
- for (bool gotone = machine().devicelist().first(network); gotone; gotone = network->next(network))
+ network_interface_iterator iter(machine().root_device());
+ for (device_network_interface *network = iter.first(); network != NULL; network = iter.next())
{
int curr = network->get_interface();
const char *title = NULL;
diff --git a/src/emu/uiswlist.c b/src/emu/uiswlist.c
index 136e142eab4..44fcb9efd4d 100644
--- a/src/emu/uiswlist.c
+++ b/src/emu/uiswlist.c
@@ -157,7 +157,7 @@ ui_menu_software_list::entry_info *ui_menu_software_list::append_software_entry(
return entry;
}
-ui_menu_software_list::ui_menu_software_list(running_machine &machine, render_container *container, const software_list_config *_swlist, const char *_interface, astring &_result) : ui_menu(machine, container), result(_result)
+ui_menu_software_list::ui_menu_software_list(running_machine &machine, render_container *container, const software_list_device *_swlist, const char *_interface, astring &_result) : ui_menu(machine, container), result(_result)
{
swlist = _swlist;
interface = _interface;
@@ -171,7 +171,7 @@ ui_menu_software_list::~ui_menu_software_list()
void ui_menu_software_list::populate()
{
- const software_list *list = software_list_open(machine().options(), swlist->list_name, false, NULL);
+ const software_list *list = software_list_open(machine().options(), swlist->list_name(), false, NULL);
// build up the list of entries for the menu
if (list)
@@ -313,7 +313,7 @@ void ui_menu_software_list::handle()
}
/* list of available software lists - i.e. cartridges, floppies */
-ui_menu_software::ui_menu_software(running_machine &machine, render_container *container, const char *_interface, const software_list_config **_result) : ui_menu(machine, container)
+ui_menu_software::ui_menu_software(running_machine &machine, render_container *container, const char *_interface, const software_list_device **_result) : ui_menu(machine, container)
{
interface = _interface;
result = _result;
@@ -324,13 +324,12 @@ void ui_menu_software::populate()
bool haveCompatible = false;
// Add original software lists for this system
- for (const device_t *dev = machine().config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext())
+ software_list_device_iterator iter(machine().config().root_device());
+ for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next())
{
- const software_list_config *swlist = (const software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config();
-
- if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)
+ if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM)
{
- const software_list *list = software_list_open(machine().options(), swlist->list_name, false, NULL);
+ const software_list *list = software_list_open(machine().options(), swlist->list_name(), false, NULL);
if (list)
{
@@ -352,13 +351,11 @@ void ui_menu_software::populate()
}
// Add compatible software lists for this system
- for (const device_t *dev = machine().config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext())
+ for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next())
{
- const software_list_config *swlist = (const software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config();
-
- if (swlist->list_type == SOFTWARE_LIST_COMPATIBLE_SYSTEM)
+ if (swlist->list_type() == SOFTWARE_LIST_COMPATIBLE_SYSTEM)
{
- const software_list *list = software_list_open(machine().options(), swlist->list_name, false, NULL);
+ const software_list *list = software_list_open(machine().options(), swlist->list_name(), false, NULL);
if (list)
{
@@ -396,7 +393,7 @@ void ui_menu_software::handle()
if (event != NULL && event->iptkey == IPT_UI_SELECT) {
// ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software_list(machine(), container, (software_list_config *)event->itemref, image)));
- *result = (software_list_config *)event->itemref;
+ *result = (software_list_device *)event->itemref;
ui_menu::stack_pop(machine());
}
}
diff --git a/src/emu/uiswlist.h b/src/emu/uiswlist.h
index da92c9f5917..f914f0faedf 100644
--- a/src/emu/uiswlist.h
+++ b/src/emu/uiswlist.h
@@ -35,7 +35,7 @@ private:
class ui_menu_software_list : public ui_menu {
public:
- ui_menu_software_list(running_machine &machine, render_container *container, const software_list_config *swlist, const char *interface, astring &result);
+ ui_menu_software_list(running_machine &machine, render_container *container, const software_list_device *swlist, const char *interface, astring &result);
virtual ~ui_menu_software_list();
virtual void populate();
virtual void handle();
@@ -48,7 +48,7 @@ private:
const char *long_name;
};
- const software_list_config *swlist; /* currently selected list */
+ const software_list_device *swlist; /* currently selected list */
const char *interface;
astring &result;
entry_info *entrylist;
@@ -61,14 +61,14 @@ private:
class ui_menu_software : public ui_menu {
public:
- ui_menu_software(running_machine &machine, render_container *container, const char *interface, const software_list_config **result);
+ ui_menu_software(running_machine &machine, render_container *container, const char *interface, const software_list_device **result);
virtual ~ui_menu_software();
virtual void populate();
virtual void handle();
private:
const char *interface;
- const software_list_config **result;
+ const software_list_device **result;
};
#endif /* __UISWLIST_H__ */
diff --git a/src/emu/validity.c b/src/emu/validity.c
index 8a1ebd2e4ea..8fb14d76c82 100644
--- a/src/emu/validity.c
+++ b/src/emu/validity.c
@@ -4,8 +4,36 @@
Validity checks on internal data structures.
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
@@ -13,22 +41,15 @@
#include "hash.h"
#include "validity.h"
#include "emuopts.h"
+#include "softlist.h"
#include <ctype.h>
-/***************************************************************************
- DEBUGGING
-***************************************************************************/
-
-#define REPORT_TIMES (0)
-
-
+//**************************************************************************
+// COMPILE-TIME VALIDATION
+//**************************************************************************
-/***************************************************************************
- COMPILE-TIME VALIDATION
-***************************************************************************/
-
-/* if the following lines error during compile, your PTR64 switch is set incorrectly in the makefile */
+// if the following lines error during compile, your PTR64 switch is set incorrectly in the makefile
#ifdef PTR64
UINT8 your_ptr64_flag_is_wrong[(int)(sizeof(void *) - 7)];
#else
@@ -37,131 +58,332 @@ UINT8 your_ptr64_flag_is_wrong[(int)(5 - sizeof(void *))];
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
-typedef tagmap_t<const game_driver *> game_driver_map;
+extern const device_type *s_devices_sorted[];
+extern int m_device_count;
-typedef tagmap_t<FPTR> int_map;
-class region_entry
-{
-public:
- region_entry()
- : length(0) { }
- astring tag;
- UINT32 length;
-};
+//**************************************************************************
+// INLINE FUNCTIONS
+//**************************************************************************
+//-------------------------------------------------
+// ioport_string_from_index - return an indexed
+// string from the I/O port system
+//-------------------------------------------------
-class region_array
+inline const char *validity_checker::ioport_string_from_index(UINT32 index)
{
-public:
- region_entry entries[256];
-};
-
-
-extern const device_type *s_devices_sorted[];
-extern int m_device_count;
+ return input_port_string_from_token((const char *)(FPTR)index);
+}
-/***************************************************************************
- INLINE FUNCTIONS
-***************************************************************************/
-/*-------------------------------------------------
- input_port_string_from_index - return an
- indexed string from the input port system
--------------------------------------------------*/
+//-------------------------------------------------
+// get_defstr_index - return the index of the
+// string assuming it is one of the default
+// strings
+//-------------------------------------------------
-INLINE const char *input_port_string_from_index(UINT32 index)
+inline int validity_checker::get_defstr_index(const char *string, bool suppress_error)
{
- return input_port_string_from_token((const char *)(FPTR)index);
+ // check for strings that should be DEF_STR
+ int strindex = m_defstr_map.find(string);
+ if (!suppress_error && strindex != 0 && string != ioport_string_from_index(strindex))
+ mame_printf_error("Must use DEF_STR( %s )\n", string);
+ return strindex;
}
-/*-------------------------------------------------
- validate_tag - ensure that the given tag
- meets the general requirements
--------------------------------------------------*/
+//-------------------------------------------------
+// validate_tag - ensure that the given tag
+// meets the general requirements
+//-------------------------------------------------
-bool validate_tag(const game_driver &driver, const char *object, const char *tag)
+void validity_checker::validate_tag(const char *tag)
{
- const char *validchars = "abcdefghijklmnopqrstuvwxyz0123456789_.:";
- const char *begin = strrchr(tag, ':');
- const char *p;
- bool error = false;
-
- /* some common names that are now deprecated */
- if (strcmp(tag, "main") == 0 ||
- strcmp(tag, "audio") == 0 ||
- strcmp(tag, "sound") == 0 ||
- strcmp(tag, "left") == 0 ||
- strcmp(tag, "right") == 0)
- {
- mame_printf_error("%s: %s has invalid generic tag '%s'\n", driver.source_file, driver.name, tag);
- error = true;
- }
+ // some common names that are now deprecated
+ if (strcmp(tag, "main") == 0 || strcmp(tag, "audio") == 0 || strcmp(tag, "sound") == 0 || strcmp(tag, "left") == 0 || strcmp(tag, "right") == 0)
+ mame_printf_error("Invalid generic tag '%s' used\n", tag);
- for (p = tag; *p != 0; p++)
+ // scan for invalid characters
+ static const char *validchars = "abcdefghijklmnopqrstuvwxyz0123456789_.:^$";
+ for (const char *p = tag; *p != 0; p++)
{
+ // only lower-case permitted
if (*p != tolower((UINT8)*p))
{
- mame_printf_error("%s: %s has %s with tag '%s' containing upper-case characters\n", driver.source_file, driver.name, object, tag);
- error = true;
+ mame_printf_error("Tag '%s' contains upper-case characters\n", tag);
break;
}
if (*p == ' ')
{
- mame_printf_error("%s: %s has %s with tag '%s' containing spaces\n", driver.source_file, driver.name, object, tag);
- error = true;
+ mame_printf_error("Tag '%s' contains spaces\n", tag);
break;
}
if (strchr(validchars, *p) == NULL)
{
- mame_printf_error("%s: %s has %s with tag '%s' containing invalid character '%c'\n", driver.source_file, driver.name, object, tag, *p);
- error = true;
+ mame_printf_error("Tag '%s' contains invalid character '%c'\n", tag, *p);
break;
}
}
+ // find the start of the final tag
+ const char *begin = strrchr(tag, ':');
if (begin == NULL)
begin = tag;
else
begin += 1;
+ // 0-length = bad
if (strlen(begin) == 0)
+ mame_printf_error("Found 0-length tag\n");
+
+ // too short/too long = bad
+ if (strlen(begin) < MIN_TAG_LENGTH)
+ mame_printf_error("Tag '%s' is too short (must be at least %d characters)\n", tag, MIN_TAG_LENGTH);
+ if (strlen(begin) > MAX_TAG_LENGTH)
+ mame_printf_error("Tag '%s' is too longer (must be less than %d characters)\n", tag, MAX_TAG_LENGTH);
+}
+
+
+
+//**************************************************************************
+// VALIDATION FUNCTIONS
+//**************************************************************************
+
+//-------------------------------------------------
+// validity_checker - constructor
+//-------------------------------------------------
+
+validity_checker::validity_checker(emu_options &options)
+ : m_drivlist(options),
+ m_errors(0),
+ m_warnings(0),
+ m_current_driver(NULL),
+ m_current_config(NULL),
+ m_current_device(NULL),
+ m_current_ioport(NULL)
+{
+ // pre-populate the defstr map with all the default strings
+ for (int strnum = 1; strnum < INPUT_STRING_COUNT; strnum++)
{
- mame_printf_error("%s: %s has %s with 0-length tag\n", driver.source_file, driver.name, object);
- error = true;
+ const char *string = ioport_string_from_index(strnum);
+ if (string != NULL)
+ m_defstr_map.add(string, strnum, false);
}
- if (strlen(begin) < MIN_TAG_LENGTH)
+}
+
+
+//-------------------------------------------------
+// check_driver - check a single driver
+//-------------------------------------------------
+
+void validity_checker::check_driver(const game_driver &driver)
+{
+ // simply validate the one driver
+ validate_begin();
+ validate_one(driver);
+ validate_end();
+}
+
+
+//-------------------------------------------------
+// check_shared_source - check all drivers that
+// share the same source file as the given driver
+//-------------------------------------------------
+
+void validity_checker::check_shared_source(const game_driver &driver)
+{
+ // initialize
+ validate_begin();
+
+ // then iterate over all drivers and check the ones that share the same source file
+ m_drivlist.reset();
+ while (m_drivlist.next())
+ if (strcmp(driver.source_file, m_drivlist.driver().source_file) == 0)
+ validate_one(m_drivlist.driver());
+
+ // cleanup
+ validate_end();
+}
+
+
+//-------------------------------------------------
+// check_all - check all drivers
+//-------------------------------------------------
+
+void validity_checker::check_all()
+{
+ // start by checking core stuff
+ validate_begin();
+ validate_core();
+ validate_inlines();
+
+ // then iterate over all drivers and check them
+ m_drivlist.reset();
+ while (m_drivlist.next())
+ validate_one(m_drivlist.driver());
+
+ // cleanup
+ validate_end();
+}
+
+
+//-------------------------------------------------
+// validate_begin - prepare for validation by
+// taking over the output callbacks and resetting
+// our internal state
+//-------------------------------------------------
+
+void validity_checker::validate_begin()
+{
+ // take over error and warning outputs
+ m_saved_error_output = mame_set_output_channel(OUTPUT_CHANNEL_ERROR, output_delegate(FUNC(validity_checker::error_output), this));
+ m_saved_warning_output = mame_set_output_channel(OUTPUT_CHANNEL_WARNING, output_delegate(FUNC(validity_checker::warning_output), this));
+
+ // reset all our maps
+ m_names_map.reset();
+ m_descriptions_map.reset();
+ m_roms_map.reset();
+ m_defstr_map.reset();
+ m_region_map.reset();
+
+ // reset internal state
+ m_errors = 0;
+ m_warnings = 0;
+
+ // reset some special case state
+ software_list_device::reset_checked_lists();
+}
+
+
+//-------------------------------------------------
+// validate_end - restore output callbacks and
+// clean up
+//-------------------------------------------------
+
+void validity_checker::validate_end()
+{
+ // restore the original output callbacks
+ mame_set_output_channel(OUTPUT_CHANNEL_ERROR, m_saved_error_output);
+ mame_set_output_channel(OUTPUT_CHANNEL_WARNING, m_saved_warning_output);
+}
+
+
+//-------------------------------------------------
+// validate_drivers - master validity checker
+//-------------------------------------------------
+
+void validity_checker::validate_one(const game_driver &driver)
+{
+ // set the current driver
+ m_current_driver = &driver;
+ m_current_config = NULL;
+ m_current_device = NULL;
+ m_current_ioport = NULL;
+ m_region_map.reset();
+
+ // reset error/warning state
+ int start_errors = m_errors;
+ int start_warnings = m_warnings;
+ m_error_text.reset();
+ m_warning_text.reset();
+
+ // wrap in try/except to catch fatalerrors
+ try
{
- mame_printf_error("%s: %s has %s with tag '%s' < %d characters\n", driver.source_file, driver.name, object, tag, MIN_TAG_LENGTH);
- error = true;
+ machine_config config(driver, m_drivlist.options());
+ m_current_config = &config;
+ validate_driver();
+ validate_roms();
+ validate_inputs();
+ validate_display();
+ validate_gfx();
+ validate_devices();
+ validate_slots();
}
- if (strlen(begin) > MAX_TAG_LENGTH)
+ catch (emu_fatalerror &err)
{
- mame_printf_error("%s: %s has %s with tag '%s' > %d characters\n", driver.source_file, driver.name, object, tag, MAX_TAG_LENGTH);
- error = true;
+ mame_printf_error("Fatal error %s", err.string());
+ }
+ m_current_config = NULL;
+
+ // if we had warnings or errors, output
+ if (m_errors > start_errors || m_warnings > start_warnings)
+ {
+ astring tempstr;
+ output_via_delegate(m_saved_error_output, "Driver %s (file %s): %d errors, %d warnings\n", driver.name, core_filename_extract_base(tempstr, driver.source_file).cstr(), m_errors - start_errors, m_warnings - start_warnings);
+ if (m_errors > start_errors)
+ {
+ m_error_text.replace("\n", "\n ");
+ output_via_delegate(m_saved_error_output, "Errors:\n %s", m_error_text.cstr());
+ }
+ if (m_warnings > start_warnings)
+ {
+ m_warning_text.replace("\n", "\n ");
+ output_via_delegate(m_saved_error_output, "Warnings:\n %s", m_warning_text.cstr());
+ }
+ output_via_delegate(m_saved_error_output, "\n");
}
- return !error;
+ // reset the driver/device
+ m_current_driver = NULL;
+ m_current_config = NULL;
+ m_current_device = NULL;
+ m_current_ioport = NULL;
}
+//-------------------------------------------------
+// validate_core - validate core internal systems
+//-------------------------------------------------
-/***************************************************************************
- VALIDATION FUNCTIONS
-***************************************************************************/
+void validity_checker::validate_core()
+{
-/*-------------------------------------------------
- validate_inlines - validate inline function
- behaviors
--------------------------------------------------*/
+ // basic system checks
+ UINT8 a = 0xff;
+ UINT8 b = a + 1;
+ if (b > a) mame_printf_error("UINT8 must be 8 bits\n");
+
+ // check size of core integer types
+ if (sizeof(INT8) != 1) mame_printf_error("INT8 must be 8 bits\n");
+ if (sizeof(UINT8) != 1) mame_printf_error("UINT8 must be 8 bits\n");
+ if (sizeof(INT16) != 2) mame_printf_error("INT16 must be 16 bits\n");
+ if (sizeof(UINT16) != 2) mame_printf_error("UINT16 must be 16 bits\n");
+ if (sizeof(INT32) != 4) mame_printf_error("INT32 must be 32 bits\n");
+ if (sizeof(UINT32) != 4) mame_printf_error("UINT32 must be 32 bits\n");
+ if (sizeof(INT64) != 8) mame_printf_error("INT64 must be 64 bits\n");
+ if (sizeof(UINT64) != 8) mame_printf_error("UINT64 must be 64 bits\n");
+
+ // check pointer size
+#ifdef PTR64
+ if (sizeof(void *) != 8) mame_printf_error("PTR64 flag enabled, but was compiled for 32-bit target\n");
+#else
+ if (sizeof(void *) != 4) mame_printf_error("PTR64 flag not enabled, but was compiled for 64-bit target\n");
+#endif
+
+ // check endianness definition
+ UINT16 lsbtest = 0;
+ *(UINT8 *)&lsbtest = 0xff;
+#ifdef LSB_FIRST
+ if (lsbtest == 0xff00) mame_printf_error("LSB_FIRST specified, but running on a big-endian machine\n");
+#else
+ if (lsbtest == 0x00ff) mame_printf_error("LSB_FIRST not specified, but running on a little-endian machine\n");
+#endif
+}
+
+
+//-------------------------------------------------
+// validate_inlines - validate inline function
+// behaviors
+//-------------------------------------------------
-static bool validate_inlines(void)
+void validity_checker::validate_inlines()
{
#undef rand
volatile UINT64 testu64a = rand() ^ (rand() << 15) ^ ((UINT64)rand() << 30) ^ ((UINT64)rand() << 45);
@@ -179,9 +401,8 @@ static bool validate_inlines(void)
UINT64 resultu64, expectedu64;
INT32 remainder, expremainder;
UINT32 uremainder, expuremainder, bigu32 = 0xffffffff;
- bool error = false;
- /* use only non-zero, positive numbers */
+ // use only non-zero, positive numbers
if (testu64a == 0) testu64a++;
if (testi64a == 0) testi64a++;
else if (testi64a < 0) testi64a = -testi64a;
@@ -199,32 +420,32 @@ static bool validate_inlines(void)
resulti64 = mul_32x32(testi32a, testi32b);
expectedi64 = (INT64)testi32a * (INT64)testi32b;
if (resulti64 != expectedi64)
- { mame_printf_error("Error testing mul_32x32 (%08X x %08X) = %08X%08X (expected %08X%08X)\n", testi32a, testi32b, (UINT32)(resulti64 >> 32), (UINT32)resulti64, (UINT32)(expectedi64 >> 32), (UINT32)expectedi64); error = true; }
+ mame_printf_error("Error testing mul_32x32 (%08X x %08X) = %08X%08X (expected %08X%08X)\n", testi32a, testi32b, (UINT32)(resulti64 >> 32), (UINT32)resulti64, (UINT32)(expectedi64 >> 32), (UINT32)expectedi64);
resultu64 = mulu_32x32(testu32a, testu32b);
expectedu64 = (UINT64)testu32a * (UINT64)testu32b;
if (resultu64 != expectedu64)
- { mame_printf_error("Error testing mulu_32x32 (%08X x %08X) = %08X%08X (expected %08X%08X)\n", testu32a, testu32b, (UINT32)(resultu64 >> 32), (UINT32)resultu64, (UINT32)(expectedu64 >> 32), (UINT32)expectedu64); error = true; }
+ mame_printf_error("Error testing mulu_32x32 (%08X x %08X) = %08X%08X (expected %08X%08X)\n", testu32a, testu32b, (UINT32)(resultu64 >> 32), (UINT32)resultu64, (UINT32)(expectedu64 >> 32), (UINT32)expectedu64);
resulti32 = mul_32x32_hi(testi32a, testi32b);
expectedi32 = ((INT64)testi32a * (INT64)testi32b) >> 32;
if (resulti32 != expectedi32)
- { mame_printf_error("Error testing mul_32x32_hi (%08X x %08X) = %08X (expected %08X)\n", testi32a, testi32b, resulti32, expectedi32); error = true; }
+ mame_printf_error("Error testing mul_32x32_hi (%08X x %08X) = %08X (expected %08X)\n", testi32a, testi32b, resulti32, expectedi32);
resultu32 = mulu_32x32_hi(testu32a, testu32b);
expectedu32 = ((INT64)testu32a * (INT64)testu32b) >> 32;
if (resultu32 != expectedu32)
- { mame_printf_error("Error testing mulu_32x32_hi (%08X x %08X) = %08X (expected %08X)\n", testu32a, testu32b, resultu32, expectedu32); error = true; }
+ mame_printf_error("Error testing mulu_32x32_hi (%08X x %08X) = %08X (expected %08X)\n", testu32a, testu32b, resultu32, expectedu32);
resulti32 = mul_32x32_shift(testi32a, testi32b, 7);
expectedi32 = ((INT64)testi32a * (INT64)testi32b) >> 7;
if (resulti32 != expectedi32)
- { mame_printf_error("Error testing mul_32x32_shift (%08X x %08X) >> 7 = %08X (expected %08X)\n", testi32a, testi32b, resulti32, expectedi32); error = true; }
+ mame_printf_error("Error testing mul_32x32_shift (%08X x %08X) >> 7 = %08X (expected %08X)\n", testi32a, testi32b, resulti32, expectedi32);
resultu32 = mulu_32x32_shift(testu32a, testu32b, 7);
expectedu32 = ((INT64)testu32a * (INT64)testu32b) >> 7;
if (resultu32 != expectedu32)
- { mame_printf_error("Error testing mulu_32x32_shift (%08X x %08X) >> 7 = %08X (expected %08X)\n", testu32a, testu32b, resultu32, expectedu32); error = true; }
+ mame_printf_error("Error testing mulu_32x32_shift (%08X x %08X) >> 7 = %08X (expected %08X)\n", testu32a, testu32b, resultu32, expectedu32);
while ((INT64)testi32a * (INT64)0x7fffffff < testi64a)
testi64a /= 2;
@@ -234,34 +455,34 @@ static bool validate_inlines(void)
resulti32 = div_64x32(testi64a, testi32a);
expectedi32 = testi64a / (INT64)testi32a;
if (resulti32 != expectedi32)
- { mame_printf_error("Error testing div_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testi64a >> 32), (UINT32)testi64a, testi32a, resulti32, expectedi32); error = true; }
+ mame_printf_error("Error testing div_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testi64a >> 32), (UINT32)testi64a, testi32a, resulti32, expectedi32);
resultu32 = divu_64x32(testu64a, testu32a);
expectedu32 = testu64a / (UINT64)testu32a;
if (resultu32 != expectedu32)
- { mame_printf_error("Error testing divu_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testu64a >> 32), (UINT32)testu64a, testu32a, resultu32, expectedu32); error = true; }
+ mame_printf_error("Error testing divu_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testu64a >> 32), (UINT32)testu64a, testu32a, resultu32, expectedu32);
resulti32 = div_64x32_rem(testi64a, testi32a, &remainder);
expectedi32 = testi64a / (INT64)testi32a;
expremainder = testi64a % (INT64)testi32a;
if (resulti32 != expectedi32 || remainder != expremainder)
- { mame_printf_error("Error testing div_64x32_rem (%08X%08X / %08X) = %08X,%08X (expected %08X,%08X)\n", (UINT32)(testi64a >> 32), (UINT32)testi64a, testi32a, resulti32, remainder, expectedi32, expremainder); error = true; }
+ mame_printf_error("Error testing div_64x32_rem (%08X%08X / %08X) = %08X,%08X (expected %08X,%08X)\n", (UINT32)(testi64a >> 32), (UINT32)testi64a, testi32a, resulti32, remainder, expectedi32, expremainder);
resultu32 = divu_64x32_rem(testu64a, testu32a, &uremainder);
expectedu32 = testu64a / (UINT64)testu32a;
expuremainder = testu64a % (UINT64)testu32a;
if (resultu32 != expectedu32 || uremainder != expuremainder)
- { mame_printf_error("Error testing divu_64x32_rem (%08X%08X / %08X) = %08X,%08X (expected %08X,%08X)\n", (UINT32)(testu64a >> 32), (UINT32)testu64a, testu32a, resultu32, uremainder, expectedu32, expuremainder); error = true; }
+ mame_printf_error("Error testing divu_64x32_rem (%08X%08X / %08X) = %08X,%08X (expected %08X,%08X)\n", (UINT32)(testu64a >> 32), (UINT32)testu64a, testu32a, resultu32, uremainder, expectedu32, expuremainder);
resulti32 = mod_64x32(testi64a, testi32a);
expectedi32 = testi64a % (INT64)testi32a;
if (resulti32 != expectedi32)
- { mame_printf_error("Error testing mod_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testi64a >> 32), (UINT32)testi64a, testi32a, resulti32, expectedi32); error = true; }
+ mame_printf_error("Error testing mod_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testi64a >> 32), (UINT32)testi64a, testi32a, resulti32, expectedi32);
resultu32 = modu_64x32(testu64a, testu32a);
expectedu32 = testu64a % (UINT64)testu32a;
if (resultu32 != expectedu32)
- { mame_printf_error("Error testing modu_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testu64a >> 32), (UINT32)testu64a, testu32a, resultu32, expectedu32); error = true; }
+ mame_printf_error("Error testing modu_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testu64a >> 32), (UINT32)testu64a, testu32a, resultu32, expectedu32);
while ((INT64)testi32a * (INT64)0x7fffffff < ((INT32)testi64a << 3))
testi64a /= 2;
@@ -271,544 +492,377 @@ static bool validate_inlines(void)
resulti32 = div_32x32_shift((INT32)testi64a, testi32a, 3);
expectedi32 = ((INT64)(INT32)testi64a << 3) / (INT64)testi32a;
if (resulti32 != expectedi32)
- { mame_printf_error("Error testing div_32x32_shift (%08X << 3) / %08X = %08X (expected %08X)\n", (INT32)testi64a, testi32a, resulti32, expectedi32); error = true; }
+ mame_printf_error("Error testing div_32x32_shift (%08X << 3) / %08X = %08X (expected %08X)\n", (INT32)testi64a, testi32a, resulti32, expectedi32);
resultu32 = divu_32x32_shift((UINT32)testu64a, testu32a, 3);
expectedu32 = ((UINT64)(UINT32)testu64a << 3) / (UINT64)testu32a;
if (resultu32 != expectedu32)
- { mame_printf_error("Error testing divu_32x32_shift (%08X << 3) / %08X = %08X (expected %08X)\n", (UINT32)testu64a, testu32a, resultu32, expectedu32); error = true; }
+ mame_printf_error("Error testing divu_32x32_shift (%08X << 3) / %08X = %08X (expected %08X)\n", (UINT32)testu64a, testu32a, resultu32, expectedu32);
if (fabs(recip_approx(100.0) - 0.01) > 0.0001)
- { mame_printf_error("Error testing recip_approx\n"); error = true; }
+ mame_printf_error("Error testing recip_approx\n");
testi32a = (testi32a & 0x0000ffff) | 0x400000;
if (count_leading_zeros(testi32a) != 9)
- { mame_printf_error("Error testing count_leading_zeros\n"); error = true; }
+ mame_printf_error("Error testing count_leading_zeros\n");
testi32a = (testi32a | 0xffff0000) & ~0x400000;
if (count_leading_ones(testi32a) != 9)
- { mame_printf_error("Error testing count_leading_ones\n"); error = true; }
+ mame_printf_error("Error testing count_leading_ones\n");
testi32b = testi32a;
if (compare_exchange32(&testi32a, testi32b, 1000) != testi32b || testi32a != 1000)
- { mame_printf_error("Error testing compare_exchange32\n"); error = true; }
+ mame_printf_error("Error testing compare_exchange32\n");
#ifdef PTR64
testi64b = testi64a;
if (compare_exchange64(&testi64a, testi64b, 1000) != testi64b || testi64a != 1000)
- { mame_printf_error("Error testing compare_exchange64\n"); error = true; }
+ mame_printf_error("Error testing compare_exchange64\n");
#endif
if (atomic_exchange32(&testi32a, testi32b) != 1000)
- { mame_printf_error("Error testing atomic_exchange32\n"); error = true; }
+ mame_printf_error("Error testing atomic_exchange32\n");
if (atomic_add32(&testi32a, 45) != testi32b + 45)
- { mame_printf_error("Error testing atomic_add32\n"); error = true; }
+ mame_printf_error("Error testing atomic_add32\n");
if (atomic_increment32(&testi32a) != testi32b + 46)
- { mame_printf_error("Error testing atomic_increment32\n"); error = true; }
+ mame_printf_error("Error testing atomic_increment32\n");
if (atomic_decrement32(&testi32a) != testi32b + 45)
- { mame_printf_error("Error testing atomic_decrement32\n"); error = true; }
-
- return error;
+ mame_printf_error("Error testing atomic_decrement32\n");
}
-/*-------------------------------------------------
- validate_driver - validate basic driver
- information
--------------------------------------------------*/
+//-------------------------------------------------
+// validate_driver - validate basic driver
+// information
+//-------------------------------------------------
-static bool validate_driver(driver_enumerator &drivlist, game_driver_map &names, game_driver_map &descriptions)
+void validity_checker::validate_driver()
{
- const game_driver &driver = drivlist.driver();
- const machine_config &config = drivlist.config();
- const char *compatible_with;
- bool error = FALSE, is_clone;
- const char *s;
-
- enum { NAME_LEN_PARENT = 8, NAME_LEN_CLONE = 16 };
-
- /* check for duplicate names */
- if (names.add(driver.name, &driver, FALSE) == TMERR_DUPLICATE)
+ // check for duplicate names
+ astring tempstr;
+ if (m_names_map.add(m_current_driver->name, m_current_driver, false) == TMERR_DUPLICATE)
{
- const game_driver *match = names.find(driver.name);
- mame_printf_error("%s: %s is a duplicate name (%s, %s)\n", driver.source_file, driver.name, match->source_file, match->name);
- error = true;
+ const game_driver *match = m_names_map.find(m_current_driver->name);
+ mame_printf_error("Driver name is a duplicate of %s(%s)\n", core_filename_extract_base(tempstr, match->source_file).cstr(), match->name);
}
- /* check for duplicate descriptions */
- if (descriptions.add(driver.description, &driver, FALSE) == TMERR_DUPLICATE)
+ // check for duplicate descriptions
+ if (m_descriptions_map.add(m_current_driver->description, m_current_driver, false) == TMERR_DUPLICATE)
{
- const game_driver *match = descriptions.find(driver.description);
- mame_printf_error("%s: %s is a duplicate description (%s, %s)\n", driver.source_file, driver.description, match->source_file, match->description);
- error = true;
+ const game_driver *match = m_descriptions_map.find(m_current_driver->description);
+ mame_printf_error("Driver description is a duplicate of %s(%s)\n", core_filename_extract_base(tempstr, match->source_file).cstr(), match->name);
}
- /* determine the clone */
- is_clone = (strcmp(driver.parent, "0") != 0);
- int clone_of = drivlist.clone(driver);
- if (clone_of != -1 && (drivlist.driver(clone_of).flags & GAME_IS_BIOS_ROOT))
+ // determine if we are a clone
+ bool is_clone = (strcmp(m_current_driver->parent, "0") != 0);
+ int clone_of = m_drivlist.clone(*m_current_driver);
+ if (clone_of != -1 && (m_drivlist.driver(clone_of).flags & GAME_IS_BIOS_ROOT))
is_clone = false;
- /* if we have at least 100 drivers, validate the clone */
- /* (100 is arbitrary, but tries to avoid tiny.mak dependencies) */
+ // if we have at least 100 drivers, validate the clone
+ // (100 is arbitrary, but tries to avoid tiny.mak dependencies)
if (driver_list::total() > 100 && clone_of == -1 && is_clone)
- {
- mame_printf_error("%s: %s is a non-existant clone\n", driver.source_file, driver.parent);
- error = true;
- }
+ mame_printf_error("Driver is a clone of nonexistant driver %s\n", m_current_driver->parent);
- /* look for recursive cloning */
- if (clone_of != -1 && &drivlist.driver(clone_of) == &driver)
- {
- mame_printf_error("%s: %s is set as a clone of itself\n", driver.source_file, driver.name);
- error = true;
- }
+ // look for recursive cloning
+ if (clone_of != -1 && &m_drivlist.driver(clone_of) == m_current_driver)
+ mame_printf_error("Driver is a clone of itself\n");
- /* look for clones that are too deep */
- if (clone_of != -1 && (clone_of = drivlist.non_bios_clone(clone_of)) != -1)
- {
- mame_printf_error("%s: %s is a clone of a clone\n", driver.source_file, driver.name);
- error = true;
- }
+ // look for clones that are too deep
+ if (clone_of != -1 && (clone_of = m_drivlist.non_bios_clone(clone_of)) != -1)
+ mame_printf_error("Driver is a clone of a clone\n");
- /* make sure the driver name is 8 chars or less */
- if ((is_clone && strlen(driver.name) > NAME_LEN_CLONE) || ((!is_clone) && strlen(driver.name) > NAME_LEN_PARENT))
- {
- mame_printf_error("%s: %s %s driver name must be %d characters or less\n", driver.source_file, driver.name,
- is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT);
- error = true;
- }
+ // make sure the driver name is not too long
+ if (!is_clone && strlen(m_current_driver->name) > 8)
+ mame_printf_error("Parent driver name must be 8 characters or less\n");
+ if (is_clone && strlen(m_current_driver->name) > 16)
+ mame_printf_error("Clone driver name must be 16 characters or less\n");
- /* make sure the year is only digits, '?' or '+' */
- for (s = driver.year; *s; s++)
+ // make sure the year is only digits, '?' or '+'
+ for (const char *s = m_current_driver->year; *s != 0; s++)
if (!isdigit((UINT8)*s) && *s != '?' && *s != '+')
{
- mame_printf_error("%s: %s has an invalid year '%s'\n", driver.source_file, driver.name, driver.year);
- error = true;
+ mame_printf_error("Driver has an invalid year '%s'\n", m_current_driver->year);
break;
}
- /* normalize driver->compatible_with */
- compatible_with = driver.compatible_with;
- if ((compatible_with != NULL) && !strcmp(compatible_with, "0"))
+ // normalize driver->compatible_with
+ const char *compatible_with = m_current_driver->compatible_with;
+ if (compatible_with != NULL && strcmp(compatible_with, "0") == 0)
compatible_with = NULL;
- /* check for this driver being compatible with a non-existant driver */
- if ((compatible_with != NULL) && (drivlist.find(driver.compatible_with) == -1))
- {
- mame_printf_error("%s: is compatible with %s, which is not in drivers[]\n", driver.name, driver.compatible_with);
- error = true;
- }
+ // check for this driver being compatible with a non-existant driver
+ if (compatible_with != NULL && m_drivlist.find(m_current_driver->compatible_with) == -1)
+ mame_printf_error("Driver is listed as compatible with nonexistant driver %s\n", m_current_driver->compatible_with);
- /* check for clone_of and compatible_with being specified at the same time */
- if ((drivlist.clone(driver) != -1) && (compatible_with != NULL))
- {
- mame_printf_error("%s: both compatible_with and clone_of are specified\n", driver.name);
- error = true;
- }
+ // check for clone_of and compatible_with being specified at the same time
+ if (m_drivlist.clone(*m_current_driver) != -1 && compatible_with != NULL)
+ mame_printf_error("Driver cannot be both a clone and listed as compatible with another system\n");
- /* find any recursive dependencies on the current driver */
- for (int other_drv = drivlist.compatible_with(driver); other_drv != -1; other_drv = drivlist.compatible_with(other_drv))
- {
- if (&driver == &drivlist.driver(other_drv))
+ // find any recursive dependencies on the current driver
+ for (int other_drv = m_drivlist.compatible_with(*m_current_driver); other_drv != -1; other_drv = m_drivlist.compatible_with(other_drv))
+ if (m_current_driver == &m_drivlist.driver(other_drv))
{
- mame_printf_error("%s: recursive compatibility\n", driver.name);
- error = true;
+ mame_printf_error("Driver is recursively compatible with itself\n");
break;
}
- }
-
- /* make sure sound-less drivers are flagged */
- const device_sound_interface *sound;
- if ((driver.flags & GAME_IS_BIOS_ROOT) == 0 && !config.devicelist().first(sound) && (driver.flags & GAME_NO_SOUND) == 0 && (driver.flags & GAME_NO_SOUND_HW) == 0)
- {
- mame_printf_error("%s: %s missing GAME_NO_SOUND flag\n", driver.source_file, driver.name);
- error = true;
- }
- return error;
+ // make sure sound-less drivers are flagged
+ sound_interface_iterator iter(m_current_config->root_device());
+ if ((m_current_driver->flags & GAME_IS_BIOS_ROOT) == 0 && iter.first() == NULL && (m_current_driver->flags & GAME_NO_SOUND) == 0 && (m_current_driver->flags & GAME_NO_SOUND_HW) == 0)
+ mame_printf_error("Driver is missing GAME_NO_SOUND flag\n");
}
-/*-------------------------------------------------
- validate_roms - validate ROM definitions
--------------------------------------------------*/
+//-------------------------------------------------
+// validate_roms - validate ROM definitions
+//-------------------------------------------------
-static bool validate_roms(driver_enumerator &drivlist, region_array *rgninfo, game_driver_map &roms)
+void validity_checker::validate_roms()
{
- const game_driver &driver = drivlist.driver();
- const machine_config &config = drivlist.config();
- int bios_flags = 0, last_bios = 0;
- const char *last_rgnname = "???";
- const char *last_name = "???";
- region_entry *currgn = NULL;
- int items_since_region = 1;
- bool error = false;
-
- const rom_source *first_source = rom_first_source(config);
-
- /* iterate, starting with the driver's ROMs and continuing with device ROMs */
- for (const rom_source *source = rom_first_source(config); source != NULL; source = rom_next_source(*source))
+ // iterate, starting with the driver's ROMs and continuing with device ROMs
+ for (const rom_source *source = rom_first_source(*m_current_config); source != NULL; source = rom_next_source(*source))
{
- /* scan the ROM entries */
+ // for non-root devices, track the current device
+ m_current_device = (source == &m_current_config->root_device()) ? NULL : source;
+
+ // scan the ROM entries for this device
+ const char *last_region_name = "???";
+ const char *last_name = "???";
+ UINT32 current_length = 0;
+ int items_since_region = 1;
+ int last_bios = 0;
+ int total_files = 0;
for (const rom_entry *romp = rom_first_region(*source); !ROMENTRY_ISEND(romp); romp++)
{
- /* if this is a region, make sure it's valid, and record the length */
+ // if this is a region, make sure it's valid, and record the length
if (ROMENTRY_ISREGION(romp))
{
- const char *regiontag = ROMREGION_GETTAG(romp);
-
- /* if we haven't seen any items since the last region, print a warning */
+ // if we haven't seen any items since the last region, print a warning
if (items_since_region == 0)
- mame_printf_warning("%s: %s has empty ROM region '%s' (warning)\n", driver.source_file, driver.name, last_rgnname);
+ mame_printf_warning("Empty ROM region '%s' (warning)\n", last_region_name);
+
+ // reset our region tracking states
+ const char *basetag = ROMREGION_GETTAG(romp);
items_since_region = (ROMREGION_ISERASE(romp) || ROMREGION_ISDISKDATA(romp)) ? 1 : 0;
- currgn = NULL;
- last_rgnname = regiontag;
+ last_region_name = basetag;
- /* check for a valid tag */
- if (regiontag == NULL)
+ // check for a valid tag
+ if (basetag == NULL)
{
- mame_printf_error("%s: %s has NULL ROM_REGION tag\n", driver.source_file, driver.name);
- error = true;
+ mame_printf_error("ROM_REGION tag with NULL name\n");
+ continue;
}
- /* find any empty entry, checking for duplicates */
- else
- {
- astring fulltag;
-
- /* iterate over all regions found so far */
- rom_region_name(fulltag, &driver, source, romp);
- for (int rgnnum = 0; rgnnum < ARRAY_LENGTH(rgninfo->entries); rgnnum++)
- {
- /* stop when we hit an empty */
- if (!rgninfo->entries[rgnnum].tag)
- {
- currgn = &rgninfo->entries[rgnnum];
- currgn->tag = fulltag;
- currgn->length = ROMREGION_GETLENGTH(romp);
- break;
- }
-
- /* fail if we hit a duplicate */
- if (fulltag == rgninfo->entries[rgnnum].tag)
- {
- mame_printf_error("%s: %s has duplicate ROM_REGION tag '%s'\n", driver.source_file, driver.name, fulltag.cstr());
- error = true;
- break;
- }
- }
- }
-
- /* validate the region tag */
- if (!validate_tag(driver, "region", regiontag))
- error = true;
+ // validate the base tag
+ validate_tag(basetag);
+
+ // generate the full tag
+ astring fulltag;
+ rom_region_name(fulltag, m_current_driver, source, romp);
+
+ // attempt to add it to the map, reporting duplicates as errors
+ current_length = ROMREGION_GETLENGTH(romp);
+ if (m_region_map.add(fulltag, current_length, false) == TMERR_DUPLICATE)
+ mame_printf_error("Multiple ROM_REGIONs with the same tag '%s' defined\n", fulltag.cstr());
}
- /* If this is a system bios, make sure it is using the next available bios number */
+ // If this is a system bios, make sure it is using the next available bios number
else if (ROMENTRY_ISSYSTEM_BIOS(romp))
{
- bios_flags = ROM_GETBIOSFLAGS(romp);
- if (last_bios+1 != bios_flags)
- {
- const char *name = ROM_GETNAME(romp);
- mame_printf_error("%s: %s has non-sequential bios %s\n", driver.source_file, driver.name, name);
- error = true;
- }
+ int bios_flags = ROM_GETBIOSFLAGS(romp);
+ if (bios_flags != last_bios + 1)
+ mame_printf_error("Non-sequential bios %s (specified as %d, expected to be %d)\n", ROM_GETNAME(romp), bios_flags, last_bios + 1);
last_bios = bios_flags;
}
- /* if this is a file, make sure it is properly formatted */
+ // if this is a file, make sure it is properly formatted
else if (ROMENTRY_ISFILE(romp))
{
- const char *s;
-
- items_since_region++;
-
- /* track the last filename we found */
+ // track the last filename we found
last_name = ROM_GETNAME(romp);
+ total_files++;
- /* make sure it's all lowercase */
- for (s = last_name; *s; s++)
+ // make sure it's all lowercase
+ for (const char *s = last_name; *s != 0; s++)
if (tolower((UINT8)*s) != *s)
{
- mame_printf_error("%s: %s has upper case ROM name %s\n", driver.source_file, driver.name, last_name);
- error = true;
+ mame_printf_error("ROM name '%s' contains upper case characters\n", last_name);
break;
}
- /* make sure the hash is valid */
+ // make sure the hash is valid
hash_collection hashes;
if (!hashes.from_internal_string(ROM_GETHASHDATA(romp)))
- {
- mame_printf_error("%s: rom '%s' has an invalid hash string '%s'\n", driver.name, last_name, ROM_GETHASHDATA(romp));
- error = true;
- }
+ mame_printf_error("ROM '%s' has an invalid hash string '%s'\n", last_name, ROM_GETHASHDATA(romp));
}
- // count copies/fills as valid items
- else if (ROMENTRY_ISCOPY(romp) || ROMENTRY_ISFILL(romp))
- items_since_region++;
-
- /* for any non-region ending entries, make sure they don't extend past the end */
- if (!ROMENTRY_ISREGIONEND(romp) && currgn != NULL)
+ // for any non-region ending entries, make sure they don't extend past the end
+ if (!ROMENTRY_ISREGIONEND(romp) && current_length > 0)
{
items_since_region++;
-
- if (ROM_GETOFFSET(romp) + ROM_GETLENGTH(romp) > currgn->length)
- {
- mame_printf_error("%s: %s has ROM %s extending past the defined memory region\n", driver.source_file, driver.name, last_name);
- error = true;
- }
+ if (ROM_GETOFFSET(romp) + ROM_GETLENGTH(romp) > current_length)
+ mame_printf_error("ROM '%s' extends past the defined memory region\n", last_name);
}
}
- /* final check for empty regions */
+ // final check for empty regions
if (items_since_region == 0)
- mame_printf_warning("%s: %s has empty ROM region (warning)\n", driver.source_file, driver.name);
+ mame_printf_warning("Empty ROM region '%s' (warning)\n", last_region_name);
- if (source!=first_source) {
- // check for device roms
- device_type type = source->type();
- int cnt = 0;
- for (const rom_entry *romp = rom_first_region(*source); !ROMENTRY_ISEND(romp); romp++)
- {
- if (ROMENTRY_ISFILE(romp)) {
- cnt++;
- }
- }
- if (cnt > 0) {
- bool found = false;
- for(int i=0;i<m_device_count;i++) {
- if (type==*s_devices_sorted[i])
- {
- found = true;
- break;
- }
+ // make sure each device is listed in the device list if it loads ROMs
+ if (m_current_device != NULL && total_files > 0)
+ {
+ // scan the list of devices for this device type
+ bool found = false;
+ for (int i = 0; i < m_device_count; i++)
+ if (m_current_device->type() == *s_devices_sorted[i])
+ {
+ found = true;
+ break;
}
- if (!found)
- mame_printf_error("Device %s is not listed in device list (mame_dev.lst / mess_dev.lst)\n", source->shortname());
- }
+
+ // if not found, report an error
+ if (!found)
+ mame_printf_error("Device %s is not listed in device list (mame_dev.lst / mess_dev.lst)\n", m_current_device->shortname());
}
- }
- return error;
+ // reset the current device
+ m_current_device = NULL;
+ }
}
-/*-------------------------------------------------
- validate_display - validate display
- configurations
--------------------------------------------------*/
+//-------------------------------------------------
+// validate_display - validate display
+// configurations
+//-------------------------------------------------
-static bool validate_display(driver_enumerator &drivlist)
+void validity_checker::validate_display()
{
- const game_driver &driver = drivlist.driver();
- const machine_config &config = drivlist.config();
+ // iterate over screen devices looking for paletted screens
+ screen_device_iterator iter(m_current_config->root_device());
bool palette_modes = false;
- bool error = false;
-
- for (const screen_device *scrconfig = config.first_screen(); scrconfig != NULL; scrconfig = scrconfig->next_screen())
+ for (const screen_device *scrconfig = iter.first(); scrconfig != NULL; scrconfig = iter.next())
if (scrconfig->format() == BITMAP_FORMAT_IND16)
palette_modes = true;
- /* check for empty palette */
- if (palette_modes && config.m_total_colors == 0)
- {
- mame_printf_error("%s: %s has zero palette entries\n", driver.source_file, driver.name);
- error = true;
- }
-
- return error;
+ // check for empty palette
+ if (palette_modes && m_current_config->m_total_colors == 0)
+ mame_printf_error("Driver has zero palette entries but uses a palette-based bitmap format\n");
}
-/*-------------------------------------------------
- validate_gfx - validate graphics decoding
- configuration
--------------------------------------------------*/
+//-------------------------------------------------
+// validate_gfx - validate graphics decoding
+// configuration
+//-------------------------------------------------
-static bool validate_gfx(driver_enumerator &drivlist, region_array *rgninfo)
+void validity_checker::validate_gfx()
{
- const game_driver &driver = drivlist.driver();
- const machine_config &config = drivlist.config();
- bool error = false;
- int gfxnum;
-
- /* bail if no gfx */
- if (!config.m_gfxdecodeinfo)
- return false;
+ // bail if no gfx
+ if (!m_current_config->m_gfxdecodeinfo)
+ return;
- /* iterate over graphics decoding entries */
- for (gfxnum = 0; gfxnum < MAX_GFX_ELEMENTS && config.m_gfxdecodeinfo[gfxnum].gfxlayout != NULL; gfxnum++)
+ // iterate over graphics decoding entries
+ for (int gfxnum = 0; gfxnum < MAX_GFX_ELEMENTS && m_current_config->m_gfxdecodeinfo[gfxnum].gfxlayout != NULL; gfxnum++)
{
- const gfx_decode_entry *gfx = &config.m_gfxdecodeinfo[gfxnum];
- const char *region = gfx->memory_region;
- int xscale = (config.m_gfxdecodeinfo[gfxnum].xscale == 0) ? 1 : config.m_gfxdecodeinfo[gfxnum].xscale;
- int yscale = (config.m_gfxdecodeinfo[gfxnum].yscale == 0) ? 1 : config.m_gfxdecodeinfo[gfxnum].yscale;
- const gfx_layout *gl = gfx->gfxlayout;
- int israw = (gl->planeoffset[0] == GFX_RAW);
- int planes = gl->planes;
- UINT16 width = gl->width;
- UINT16 height = gl->height;
- UINT32 total = gl->total;
-
- /* make sure the region exists */
+ const gfx_decode_entry &gfx = m_current_config->m_gfxdecodeinfo[gfxnum];
+ const gfx_layout &layout = *gfx.gfxlayout;
+
+ // make sure the region exists
+ const char *region = gfx.memory_region;
if (region != NULL)
{
- int rgnnum;
-
- /* loop over gfx regions */
- for (rgnnum = 0; rgnnum < ARRAY_LENGTH(rgninfo->entries); rgnnum++)
- {
- /* stop if we hit an empty */
- if (!rgninfo->entries[rgnnum].tag)
- {
- mame_printf_error("%s: %s has gfx[%d] referencing non-existent region '%s'\n", driver.source_file, driver.name, gfxnum, region);
- error = true;
- break;
- }
-
- /* if we hit a match, check against the length */
- if (rgninfo->entries[rgnnum].tag == region)
- {
- /* if we have a valid region, and we're not using auto-sizing, check the decode against the region length */
- if (!IS_FRAC(total))
- {
- int len, avail, plane, start;
- UINT32 charincrement = gl->charincrement;
- const UINT32 *poffset = gl->planeoffset;
+ // resolve the region
+ astring gfxregion;
+ m_current_config->root_device().subtag(gfxregion, region);
- /* determine which plane is the largest */
- start = 0;
- for (plane = 0; plane < planes; plane++)
- if (poffset[plane] > start)
- start = poffset[plane];
- start &= ~(charincrement - 1);
+ // loop over gfx regions
+ UINT32 region_length = m_region_map.find(gfxregion);
+ if (region_length == 0)
+ mame_printf_error("gfx[%d] references non-existent region '%s'\n", gfxnum, region);
- /* determine the total length based on this info */
- len = total * charincrement;
-
- /* do we have enough space in the region to cover the whole decode? */
- avail = rgninfo->entries[rgnnum].length - (gfx->start & ~(charincrement/8-1));
-
- /* if not, this is an error */
- if ((start + len) / 8 > avail)
- {
- mame_printf_error("%s: %s has gfx[%d] extending past allocated memory of region '%s'\n", driver.source_file, driver.name, gfxnum, region);
- error = true;
- }
- }
- break;
- }
+ // if we have a valid region, and we're not using auto-sizing, check the decode against the region length
+ else if (!IS_FRAC(layout.total))
+ {
+ // determine which plane is at the largest offset
+ int start = 0;
+ for (int plane = 0; plane < layout.planes; plane++)
+ if (layout.planeoffset[plane] > start)
+ start = layout.planeoffset[plane];
+ start &= ~(layout.charincrement - 1);
+
+ // determine the total length based on this info
+ int len = layout.total * layout.charincrement;
+
+ // do we have enough space in the region to cover the whole decode?
+ int avail = region_length - (gfx.start & ~(layout.charincrement / 8 - 1));
+
+ // if not, this is an error
+ if ((start + len) / 8 > avail)
+ mame_printf_error("gfx[%d] extends past allocated memory of region '%s'\n", gfxnum, region);
}
}
- if (israw)
+ int xscale = (m_current_config->m_gfxdecodeinfo[gfxnum].xscale == 0) ? 1 : m_current_config->m_gfxdecodeinfo[gfxnum].xscale;
+ int yscale = (m_current_config->m_gfxdecodeinfo[gfxnum].yscale == 0) ? 1 : m_current_config->m_gfxdecodeinfo[gfxnum].yscale;
+
+ // verify raw decode, which can only be full-region and have no scaling
+ if (layout.planeoffset[0] == GFX_RAW)
{
- if (total != RGN_FRAC(1,1))
- {
- mame_printf_error("%s: %s has gfx[%d] with unsupported layout total\n", driver.source_file, driver.name, gfxnum);
- error = true;
- }
-
+ if (layout.total != RGN_FRAC(1,1))
+ mame_printf_error("gfx[%d] with unsupported layout total\n", gfxnum);
if (xscale != 1 || yscale != 1)
- {
- mame_printf_error("%s: %s has gfx[%d] with unsupported xscale/yscale\n", driver.source_file, driver.name, gfxnum);
- error = true;
- }
+ mame_printf_error("gfx[%d] with unsupported xscale/yscale\n", gfxnum);
}
+
+ // verify traditional decode doesn't have too many planes or is not too large
else
{
- if (planes > MAX_GFX_PLANES)
- {
- mame_printf_error("%s: %s has gfx[%d] with invalid planes\n", driver.source_file, driver.name, gfxnum);
- error = true;
- }
-
- if (xscale * width > MAX_ABS_GFX_SIZE || yscale * height > MAX_ABS_GFX_SIZE)
- {
- mame_printf_error("%s: %s has gfx[%d] with invalid xscale/yscale\n", driver.source_file, driver.name, gfxnum);
- error = true;
- }
+ if (layout.planes > MAX_GFX_PLANES)
+ mame_printf_error("gfx[%d] with invalid planes\n", gfxnum);
+ if (xscale * layout.width > MAX_ABS_GFX_SIZE || yscale * layout.height > MAX_ABS_GFX_SIZE)
+ mame_printf_error("gfx[%d] with invalid xscale/yscale\n", gfxnum);
}
}
-
- return error;
-}
-
-
-/*-------------------------------------------------
- get_defstr_index - return the index of the
- string assuming it is one of the default
- strings
--------------------------------------------------*/
-
-static int get_defstr_index(int_map &defstr_map, const char *name, const game_driver &driver, bool *error)
-{
- /* check for strings that should be DEF_STR */
- int strindex = defstr_map.find(name);
- if (strindex != 0 && name != input_port_string_from_index(strindex) && error != NULL)
- {
- mame_printf_error("%s: %s must use DEF_STR( %s )\n", driver.source_file, driver.name, name);
- *error = true;
- }
-
- return strindex;
}
-/*-------------------------------------------------
- validate_analog_input_field - validate an
- analog input field
--------------------------------------------------*/
+//-------------------------------------------------
+// validate_analog_input_field - validate an
+// analog input field
+//-------------------------------------------------
-static void validate_analog_input_field(input_field_config *field, const game_driver &driver, bool *error)
+void validity_checker::validate_analog_input_field(input_field_config &field)
{
- INT32 analog_max = field->max;
- INT32 analog_min = field->min;
- int shift;
+ // analog ports must have a valid sensitivity
+ if (field.sensitivity == 0)
+ mame_printf_error("Analog port with zero sensitivity\n");
- if (field->type == IPT_POSITIONAL || field->type == IPT_POSITIONAL_V)
- {
- for (shift = 0; (shift <= 31) && (~field->mask & (1 << shift)); shift++) ;
- /* convert the positional max value to be in the bitmask for testing */
- analog_max = (analog_max - 1) << shift;
+ // check that the default falls in the bitmask range
+ if (field.defvalue & ~field.mask)
+ mame_printf_error("Analog port with a default value (%X) out of the bitmask range (%X)\n", field.defvalue, field.mask);
- /* positional port size must fit in bits used */
- if (((field->mask >> shift) + 1) < field->max)
- {
- mame_printf_error("%s: %s has an analog port with a positional port size bigger then the mask size\n", driver.source_file, driver.name);
- *error = true;
- }
- }
- else
+ // tests for positional devices
+ if (field.type == IPT_POSITIONAL || field.type == IPT_POSITIONAL_V)
{
- /* only positional controls use PORT_WRAPS */
- if (field->flags & ANALOG_FLAG_WRAPS)
- {
- mame_printf_error("%s: %s only positional analog ports use PORT_WRAPS\n", driver.source_file, driver.name);
- *error = true;
- }
- }
+ int shift;
+ for (shift = 0; shift <= 31 && (~field.mask & (1 << shift)) != 0; shift++) ;
- /* analog ports must have a valid sensitivity */
- if (field->sensitivity == 0)
- {
- mame_printf_error("%s: %s has an analog port with zero sensitivity\n", driver.source_file, driver.name);
- *error = true;
- }
+ // convert the positional max value to be in the bitmask for testing
+ INT32 analog_max = field.max;
+ analog_max = (analog_max - 1) << shift;
- /* check that the default falls in the bitmask range */
- if (field->defvalue & ~field->mask)
- {
- mame_printf_error("%s: %s has an analog port with a default value out of the bitmask range\n", driver.source_file, driver.name);
- *error = true;
+ // positional port size must fit in bits used
+ if ((field.mask >> shift) + 1 < field.max)
+ mame_printf_error("Analog port with a positional port size bigger then the mask size\n");
}
- /* tests for absolute devices */
- if (field->type >= __ipt_analog_absolute_start && field->type <= __ipt_analog_absolute_end)
+ // tests for absolute devices
+ else if (field.type >= __ipt_analog_absolute_start && field.type <= __ipt_analog_absolute_end)
{
- INT32 default_value = field->defvalue;
-
- /* adjust for signed values */
+ // adjust for signed values
+ INT32 default_value = field.defvalue;
+ INT32 analog_min = field.min;
+ INT32 analog_max = field.max;
if (analog_min > analog_max)
{
analog_min = -analog_min;
@@ -816,506 +870,388 @@ static void validate_analog_input_field(input_field_config *field, const game_dr
default_value = -default_value;
}
- /* check that the default falls in the MINMAX range */
+ // check that the default falls in the MINMAX range
if (default_value < analog_min || default_value > analog_max)
- {
- mame_printf_error("%s: %s has an analog port with a default value out PORT_MINMAX range\n", driver.source_file, driver.name);
- *error = true;
- }
+ mame_printf_error("Analog port with a default value (%X) out of PORT_MINMAX range (%X-%X)\n", field.defvalue, field.min, field.max);
- /* check that the MINMAX falls in the bitmask range */
- /* we use the unadjusted min for testing */
- if (field->min & ~field->mask || analog_max & ~field->mask)
- {
- mame_printf_error("%s: %s has an analog port with a PORT_MINMAX value out of the bitmask range\n", driver.source_file, driver.name);
- *error = true;
- }
+ // check that the MINMAX falls in the bitmask range
+ // we use the unadjusted min for testing
+ if (field.min & ~field.mask || analog_max & ~field.mask)
+ mame_printf_error("Analog port with a PORT_MINMAX (%X-%X) value out of the bitmask range (%X)\n", field.min, field.max, field.mask);
- /* absolute analog ports do not use PORT_RESET */
- if (field->flags & ANALOG_FLAG_RESET)
- {
- mame_printf_error("%s: %s - absolute analog ports do not use PORT_RESET\n", driver.source_file, driver.name);
- *error = true;
- }
+ // absolute analog ports do not use PORT_RESET
+ if (field.flags & ANALOG_FLAG_RESET)
+ mame_printf_error("Absolute analog port using PORT_RESET\n");
+
+ // absolute analog ports do not use PORT_WRAPS
+ if (field.flags & ANALOG_FLAG_WRAPS)
+ mame_printf_error("Absolute analog port using PORT_WRAPS\n");
}
- /* tests for relative devices */
+ // tests for non IPT_POSITIONAL relative devices
else
{
- /* tests for non IPT_POSITIONAL relative devices */
- if (field->type != IPT_POSITIONAL && field->type != IPT_POSITIONAL_V)
- {
- /* relative devices do not use PORT_MINMAX */
- if (field->min != 0 || field->max != field->mask)
- {
- mame_printf_error("%s: %s - relative ports do not use PORT_MINMAX\n", driver.source_file, driver.name);
- *error = true;
- }
-
- /* relative devices do not use a default value */
- /* the counter is at 0 on power up */
- if (field->defvalue != 0)
- {
- mame_printf_error("%s: %s - relative ports do not use a default value other then 0\n", driver.source_file, driver.name);
- *error = true;
- }
- }
+ // relative devices do not use PORT_MINMAX
+ if (field.min != 0 || field.max != field.mask)
+ mame_printf_error("Relative port using PORT_MINMAX\n");
+
+ // relative devices do not use a default value
+ // the counter is at 0 on power up
+ if (field.defvalue != 0)
+ mame_printf_error("Relative port using non-0 default value\n");
+
+ // relative analog ports do not use PORT_WRAPS
+ if (field.flags & ANALOG_FLAG_WRAPS)
+ mame_printf_error("Absolute analog port using PORT_WRAPS\n");
}
}
-/*-------------------------------------------------
- validate_dip_settings - validate a DIP switch
- setting
--------------------------------------------------*/
+//-------------------------------------------------
+// validate_dip_settings - validate a DIP switch
+// setting
+//-------------------------------------------------
-static void validate_dip_settings(input_field_config *field, const game_driver &driver, int_map &defstr_map, bool *error)
+void validity_checker::validate_dip_settings(input_field_config &field)
{
- const char *demo_sounds = input_port_string_from_index(INPUT_STRING_Demo_Sounds);
- const char *flipscreen = input_port_string_from_index(INPUT_STRING_Flip_Screen);
+ const char *demo_sounds = ioport_string_from_index(INPUT_STRING_Demo_Sounds);
+ const char *flipscreen = ioport_string_from_index(INPUT_STRING_Flip_Screen);
UINT8 coin_list[__input_string_coinage_end + 1 - __input_string_coinage_start] = { 0 };
- const input_setting_config *setting;
- int coin_error = FALSE;
+ bool coin_error = false;
- /* iterate through the settings */
- for (setting = field->settinglist().first(); setting != NULL; setting = setting->next())
+ // iterate through the settings
+ for (const input_setting_config *setting = field.settinglist().first(); setting != NULL; setting = setting->next())
{
- int strindex = get_defstr_index(defstr_map, setting->name, driver, error);
-
- /* note any coinage strings */
+ // note any coinage strings
+ int strindex = get_defstr_index(setting->name);
if (strindex >= __input_string_coinage_start && strindex <= __input_string_coinage_end)
coin_list[strindex - __input_string_coinage_start] = 1;
- /* make sure demo sounds default to on */
- if (field->name == demo_sounds && strindex == INPUT_STRING_On && field->defvalue != setting->value)
- {
- mame_printf_error("%s: %s Demo Sounds must default to On\n", driver.source_file, driver.name);
- *error = true;
- }
+ // make sure demo sounds default to on
+ if (field.name == demo_sounds && strindex == INPUT_STRING_On && field.defvalue != setting->value)
+ mame_printf_error("Demo Sounds must default to On\n");
- /* check for bad demo sounds options */
- if (field->name == demo_sounds && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
- {
- mame_printf_error("%s: %s has wrong Demo Sounds option %s (must be Off/On)\n", driver.source_file, driver.name, setting->name);
- *error = true;
- }
+ // check for bad demo sounds options
+ if (field.name == demo_sounds && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
+ mame_printf_error("Demo Sounds option must be Off/On, not %s\n", setting->name);
- /* check for bad flip screen options */
- if (field->name == flipscreen && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
- {
- mame_printf_error("%s: %s has wrong Flip Screen option %s (must be Off/On)\n", driver.source_file, driver.name, setting->name);
- *error = true;
- }
+ // check for bad flip screen options
+ if (field.name == flipscreen && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
+ mame_printf_error("Flip Screen option must be Off/On, not %s\n", setting->name);
- /* if we have a neighbor, compare ourselves to him */
+ // if we have a neighbor, compare ourselves to him
if (setting->next() != NULL)
{
- int next_strindex = get_defstr_index(defstr_map, setting->next()->name, driver, error);
-
- /* check for inverted off/on dispswitch order */
+ // check for inverted off/on dispswitch order
+ int next_strindex = get_defstr_index(setting->next()->name, true);
if (strindex == INPUT_STRING_On && next_strindex == INPUT_STRING_Off)
- {
- mame_printf_error("%s: %s has inverted Off/On dipswitch order\n", driver.source_file, driver.name);
- *error = true;
- }
+ mame_printf_error("%s option must have Off/On options in the order: Off, On\n", field.name);
- /* check for inverted yes/no dispswitch order */
+ // check for inverted yes/no dispswitch order
else if (strindex == INPUT_STRING_Yes && next_strindex == INPUT_STRING_No)
- {
- mame_printf_error("%s: %s has inverted No/Yes dipswitch order\n", driver.source_file, driver.name);
- *error = true;
- }
+ mame_printf_error("%s option must have Yes/No options in the order: No, Yes\n", field.name);
- /* check for inverted upright/cocktail dispswitch order */
+ // check for inverted upright/cocktail dispswitch order
else if (strindex == INPUT_STRING_Cocktail && next_strindex == INPUT_STRING_Upright)
- {
- mame_printf_error("%s: %s has inverted Upright/Cocktail dipswitch order\n", driver.source_file, driver.name);
- *error = true;
- }
+ mame_printf_error("%s option must have Upright/Cocktail options in the order: Upright, Cocktail\n", field.name);
- /* check for proper coin ordering */
+ // check for proper coin ordering
else if (strindex >= __input_string_coinage_start && strindex <= __input_string_coinage_end && next_strindex >= __input_string_coinage_start && next_strindex <= __input_string_coinage_end &&
strindex >= next_strindex && memcmp(&setting->condition, &setting->next()->condition, sizeof(setting->condition)) == 0)
{
- mame_printf_error("%s: %s has unsorted coinage %s > %s\n", driver.source_file, driver.name, setting->name, setting->next()->name);
- coin_error = *error = true;
+ mame_printf_error("%s option has unsorted coinage %s > %s\n", field.name, setting->name, setting->next()->name);
+ coin_error = true;
}
}
}
- /* if we have a coin error, demonstrate the correct way */
+ // if we have a coin error, demonstrate the correct way
if (coin_error)
{
- int entry;
-
- mame_printf_error("%s: %s proper coin sort order should be:\n", driver.source_file, driver.name);
- for (entry = 0; entry < ARRAY_LENGTH(coin_list); entry++)
+ output_via_delegate(m_saved_error_output, " Note proper coin sort order should be:\n");
+ for (int entry = 0; entry < ARRAY_LENGTH(coin_list); entry++)
if (coin_list[entry])
- mame_printf_error("%s\n", input_port_string_from_index(__input_string_coinage_start + entry));
+ output_via_delegate(m_saved_error_output, " %s\n", ioport_string_from_index(__input_string_coinage_start + entry));
}
}
-/*-------------------------------------------------
- validate_inputs - validate input configuration
--------------------------------------------------*/
+//-------------------------------------------------
+// validate_condition - validate a condition
+// stored within an ioport field or setting
+//-------------------------------------------------
-static bool validate_inputs(driver_enumerator &drivlist, int_map &defstr_map, ioport_list &portlist)
+void validity_checker::validate_condition(input_condition &condition, device_t &device, int_map &port_map)
{
- input_port_config *scanport;
- input_port_config *port;
- input_field_config *field;
- const game_driver &driver = drivlist.driver();
- const machine_config &config = drivlist.config();
- int empty_string_found = FALSE;
- bool error = false;
- astring errorbuf;
-
- /* skip if no ports */
- if (driver.ipt == NULL)
- return FALSE;
-
- /* allocate the input ports */
- for (device_t *cfg = config.devicelist().first(); cfg != NULL; cfg = cfg->next())
+ // resolve the tag
+ astring porttag;
+ device.subtag(porttag, condition.tag);
+
+ // then find a matching port
+ if (port_map.find(porttag) == 0)
+ mame_printf_error("Condition referencing non-existent ioport tag '%s'\n", condition.tag);
+}
+
+
+//-------------------------------------------------
+// validate_inputs - validate input configuration
+//-------------------------------------------------
+
+void validity_checker::validate_inputs()
+{
+ int_map port_map;
+
+ // iterate over devices
+ device_iterator iter(m_current_config->root_device());
+ for (device_t *device = iter.first(); device != NULL; device = iter.next())
{
- input_port_list_init(*cfg, portlist, errorbuf);
+ // see if this device has ports; if not continue
+ if (device->input_ports() == NULL)
+ continue;
+
+ // for non-root devices, track the current device
+ m_current_device = (device == &m_current_config->root_device()) ? NULL : device;
+
+ // allocate the input ports
+ ioport_list portlist;
+ astring errorbuf;
+ input_port_list_init(*device, portlist, errorbuf);
+
+ // report any errors during construction
if (errorbuf)
- {
- mame_printf_error("%s: %s has input port errors:\n%s\n", driver.source_file, driver.name, errorbuf.cstr());
- error = true;
- }
- }
+ mame_printf_error("I/O port error during construction:\n%s\n", errorbuf.cstr());
- /* check for duplicate tags */
- for (port = portlist.first(); port != NULL; port = port->next())
- for (scanport = port->next(); scanport != NULL; scanport = scanport->next())
- if (strcmp(port->tag(), scanport->tag()) == 0)
- {
- mame_printf_error("%s: %s has a duplicate input port tag '%s'\n", driver.source_file, driver.name, port->tag());
- error = true;
- }
+ // do a first pass over ports to add their names and find duplicates
+ for (input_port_config *port = portlist.first(); port != NULL; port = port->next())
+ if (port_map.add(port->tag(), 1, false) == TMERR_DUPLICATE)
+ mame_printf_error("Multiple I/O ports with the same tag '%s' defined\n", port->tag());
- /* iterate over the results */
- for (port = portlist.first(); port != NULL; port = port->next())
- for (field = port->fieldlist().first(); field != NULL; field = field->next())
+ // iterate over ports
+ for (input_port_config *port = portlist.first(); port != NULL; port = port->next())
{
- input_setting_config *setting;
- //int strindex = 0;
-
- /* verify analog inputs */
- if (input_type_is_analog(field->type))
- validate_analog_input_field(field, driver, &error);
+ m_current_ioport = port->tag();
- /* verify dip switches */
- if (field->type == IPT_DIPSWITCH)
+ // iterate through the fields on this port
+ for (input_field_config *field = port->fieldlist().first(); field != NULL; field = field->next())
{
- /* dip switch fields must have a name */
- if (field->name == NULL)
- {
- mame_printf_error("%s: %s has a DIP switch name or setting with no name\n", driver.source_file, driver.name);
- error = true;
- }
-
- /* verify the settings list */
- validate_dip_settings(field, driver, defstr_map, &error);
- }
+ // verify analog inputs
+ if (input_type_is_analog(field->type))
+ validate_analog_input_field(*field);
- /* look for invalid (0) types which should be mapped to IPT_OTHER */
- if (field->type == IPT_INVALID)
- {
- mame_printf_error("%s: %s has an input port with an invalid type (0); use IPT_OTHER instead\n", driver.source_file, driver.name);
- error = true;
- }
+ // look for invalid (0) types which should be mapped to IPT_OTHER
+ if (field->type == IPT_INVALID)
+ mame_printf_error("Field has an invalid type (0); use IPT_OTHER instead\n");
- /* verify names */
- if (field->name != NULL)
- {
- /* check for empty string */
- if (field->name[0] == 0 && !empty_string_found)
+ // verify dip switches
+ if (field->type == IPT_DIPSWITCH)
{
- mame_printf_error("%s: %s has an input with an empty string\n", driver.source_file, driver.name);
- empty_string_found = error = true;
- }
+ // dip switch fields must have a name
+ if (field->name == NULL)
+ mame_printf_error("DIP switch has a NULL name\n");
- /* check for trailing spaces */
- if (field->name[0] != 0 && field->name[strlen(field->name) - 1] == ' ')
- {
- mame_printf_error("%s: %s input '%s' has trailing spaces\n", driver.source_file, driver.name, field->name);
- error = true;
+ // verify the settings list
+ validate_dip_settings(*field);
}
- /* check for invalid UTF-8 */
- if (!utf8_is_valid_string(field->name))
+ // verify names
+ if (field->name != NULL)
{
- mame_printf_error("%s: %s input '%s' has invalid characters\n", driver.source_file, driver.name, field->name);
- error = true;
- }
+ // check for empty string
+ if (field->name[0] == 0)
+ mame_printf_error("Field name is an empty string\n");
- /* look up the string and print an error if default strings are not used */
- /*strindex = */get_defstr_index(defstr_map, field->name, driver, &error);
- }
+ // check for trailing spaces
+ if (field->name[0] != 0 && field->name[strlen(field->name) - 1] == ' ')
+ mame_printf_error("Field '%s' has trailing spaces\n", field->name);
- /* verify conditions on the field */
- if (field->condition.tag != NULL)
- {
- /* find a matching port */
- for (scanport = portlist.first(); scanport != NULL; scanport = scanport->next()) {
- astring porttag;
- port->owner().subtag(porttag, field->condition.tag);
- if (strcmp(porttag.cstr(), scanport->tag()) == 0)
- break;
- }
- /* if none, error */
- if (scanport == NULL)
- {
- mame_printf_error("%s: %s has a condition referencing non-existent input port tag '%s'\n", driver.source_file, driver.name, field->condition.tag);
- error = true;
- }
- }
+ // check for invalid UTF-8
+ if (!utf8_is_valid_string(field->name))
+ mame_printf_error("Field '%s' has invalid characters\n", field->name);
- /* verify conditions on the settings */
- for (setting = field->settinglist().first(); setting != NULL; setting = setting->next())
- if (setting->condition.tag != NULL)
- {
- /* find a matching port */
- for (scanport = portlist.first(); scanport != NULL; scanport = scanport->next()) {
- astring porttag;
- port->owner().subtag(porttag, setting->condition.tag);
- if (strcmp(porttag.cstr(), scanport->tag()) == 0)
- break;
- }
- /* if none, error */
- if (scanport == NULL)
- {
- mame_printf_error("%s: %s has a condition referencing non-existent input port tag '%s'\n", driver.source_file, driver.name, setting->condition.tag);
- error = true;
- }
+ // look up the string and print an error if default strings are not used
+ /*strindex =get_defstr_index(defstr_map, field->name, driver, &error);*/
}
- }
- error = error || validate_natural_keyboard_statics();
+ // verify conditions on the field
+ if (field->condition.tag != NULL)
+ validate_condition(field->condition, *device, port_map);
- return error;
+ // verify conditions on the settings
+ for (input_setting_config *setting = field->settinglist().first(); setting != NULL; setting = setting->next())
+ if (setting->condition.tag != NULL)
+ validate_condition(setting->condition, *device, port_map);
+ }
+
+ // done with this port
+ m_current_ioport = NULL;
+ }
+
+ // done with this device
+ m_current_device = NULL;
+ }
}
-/*-------------------------------------------------
- validate_devices - run per-device validity
- checks
--------------------------------------------------*/
+//-------------------------------------------------
+// validate_devices - run per-device validity
+// checks
+//-------------------------------------------------
-static bool validate_devices(driver_enumerator &drivlist, const ioport_list &portlist, region_array *rgninfo)
+void validity_checker::validate_devices()
{
- bool error = false;
- const game_driver &driver = drivlist.driver();
- const machine_config &config = drivlist.config();
+ int_map device_map;
- for (const device_t *device = config.devicelist().first(); device != NULL; device = device->next())
+ // iterate over devices
+ device_iterator iter(m_current_config->root_device());
+ for (const device_t *device = iter.first(); device != NULL; device = iter.next())
{
- /* validate the device tag */
- if (!validate_tag(driver, device->name(), device->tag()))
- error = true;
+ // for non-root devices, track the current device
+ m_current_device = (device == &m_current_config->root_device()) ? NULL : device;
- /* look for duplicates */
- for (const device_t *scandevice = config.devicelist().first(); scandevice != device; scandevice = scandevice->next())
- if (strcmp(scandevice->tag(), device->tag()) == 0)
- {
- mame_printf_warning("%s: %s has multiple devices with the tag '%s'\n", driver.source_file, driver.name, device->tag());
- break;
- }
+ // validate the device tag
+ validate_tag(device->basetag());
- if (device->rom_region() != NULL && (strcmp(device->shortname(),"") == 0)) {
- mame_printf_warning("Device %s does not have short name defined\n", device->name());
- }
- /* check for device-specific validity check */
- if (device->validity_check(config.options(), driver))
- error = true;
+ // look for duplicates
+ if (device_map.add(device->tag(), 0, false) == TMERR_DUPLICATE)
+ mame_printf_error("Multiple devices with the same tag '%s' defined\n", device->tag());
+
+ // if we have a ROM region, we must have a shortname
+ if (device->rom_region() != NULL && strcmp(device->shortname(), "") == 0)
+ mame_printf_error("Device %s has ROM definition but does not have short name defined\n", device->name());
+ // check for device-specific validity check
+ device->validity_check(*this);
+
+ // done with this device
+ m_current_device = NULL;
}
- return error;
}
-/*-------------------------------------------------
- validate_slots - run per-slot validity
- checks
--------------------------------------------------*/
+//-------------------------------------------------
+// validate_slots - run per-slot validity
+// checks
+//-------------------------------------------------
-static bool validate_slots(driver_enumerator &drivlist)
+void validity_checker::validate_slots()
{
- bool error = false;
- const machine_config &config = drivlist.config();
-
- const device_slot_interface *slot = NULL;
- for (bool gotone = config.devicelist().first(slot); gotone; gotone = slot->next(slot))
+ // iterate over slots
+ slot_interface_iterator iter(m_current_config->root_device());
+ for (const device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next())
{
- const slot_interface* intf = slot->get_slot_interfaces();
+ // iterate over interfaces
+ const slot_interface *intf = slot->get_slot_interfaces();
for (int j = 0; intf[j].name != NULL; j++)
{
- device_t *dev = (*intf[j].devtype)(config, "dummy", config.devicelist().first(), 0);
+ // instantiate the device
+ device_t *dev = (*intf[j].devtype)(*m_current_config, "dummy", &m_current_config->root_device(), 0);
dev->config_complete();
+
+ // if a ROM region is present
if (dev->rom_region() != NULL)
{
- int cnt = 0;
+ bool has_romfiles = false;
for (const rom_entry *romp = rom_first_region(*dev); !ROMENTRY_ISEND(romp); romp++)
- {
- if (ROMENTRY_ISFILE(romp)) {
- cnt++;
+ if (ROMENTRY_ISFILE(romp))
+ {
+ has_romfiles = true;
+ break;
}
- }
- if (cnt > 0) {
+ if (has_romfiles)
+ {
+ // scan the list of devices for this device type
bool found = false;
- for(int i=0;i<m_device_count;i++) {
- if (intf[j].devtype==*s_devices_sorted[i])
+ for (int i = 0; i < m_device_count; i++)
+ if (dev->type() == *s_devices_sorted[i])
{
found = true;
break;
}
- }
- if (!found) {
- mame_printf_error("Device %s in slot %s is not listed in device list\n", dev->name(), intf[j].name);
- error = true;
- }
+
+ // if not found, report an error
+ if (!found)
+ mame_printf_error("Device %s in slot %s is not listed in device list (mame_dev.lst / mess_dev.lst)\n", dev->shortname(), intf[j].name);
}
}
global_free(dev);
}
}
- return error;
}
-/*-------------------------------------------------
- validate_drivers - master validity checker
--------------------------------------------------*/
+//-------------------------------------------------
+// build_output_prefix - create a prefix
+// indicating the current source file, driver,
+// and device
+//-------------------------------------------------
-void validate_drivers(emu_options &options, const game_driver *curdriver)
+void validity_checker::build_output_prefix(astring &string)
{
- osd_ticks_t prep = 0;
- osd_ticks_t driver_checks = 0;
- osd_ticks_t rom_checks = 0;
- osd_ticks_t gfx_checks = 0;
- osd_ticks_t display_checks = 0;
- osd_ticks_t input_checks = 0;
- osd_ticks_t device_checks = 0;
-
- int strnum;
- bool error = false;
- UINT16 lsbtest;
- UINT8 a, b;
-
- game_driver_map names;
- game_driver_map descriptions;
- game_driver_map roms;
- int_map defstr;
-
- /* basic system checks */
- a = 0xff;
- b = a + 1;
- if (b > a) { mame_printf_error("UINT8 must be 8 bits\n"); error = true; }
-
- if (sizeof(INT8) != 1) { mame_printf_error("INT8 must be 8 bits\n"); error = true; }
- if (sizeof(UINT8) != 1) { mame_printf_error("UINT8 must be 8 bits\n"); error = true; }
- if (sizeof(INT16) != 2) { mame_printf_error("INT16 must be 16 bits\n"); error = true; }
- if (sizeof(UINT16) != 2) { mame_printf_error("UINT16 must be 16 bits\n"); error = true; }
- if (sizeof(INT32) != 4) { mame_printf_error("INT32 must be 32 bits\n"); error = true; }
- if (sizeof(UINT32) != 4) { mame_printf_error("UINT32 must be 32 bits\n"); error = true; }
- if (sizeof(INT64) != 8) { mame_printf_error("INT64 must be 64 bits\n"); error = true; }
- if (sizeof(UINT64) != 8) { mame_printf_error("UINT64 must be 64 bits\n"); error = true; }
-#ifdef PTR64
- if (sizeof(void *) != 8) { mame_printf_error("PTR64 flag enabled, but was compiled for 32-bit target\n"); error = true; }
-#else
- if (sizeof(void *) != 4) { mame_printf_error("PTR64 flag not enabled, but was compiled for 64-bit target\n"); error = true; }
-#endif
- lsbtest = 0;
- *(UINT8 *)&lsbtest = 0xff;
-#ifdef LSB_FIRST
- if (lsbtest == 0xff00) { mame_printf_error("LSB_FIRST specified, but running on a big-endian machine\n"); error = true; }
-#else
- if (lsbtest == 0x00ff) { mame_printf_error("LSB_FIRST not specified, but running on a little-endian machine\n"); error = true; }
-#endif
+ // start empty
+ string.reset();
+
+ // if we have a current device, indicate that
+ if (m_current_device != NULL)
+ string.cat(m_current_device->name()).cat(" device '").cat(m_current_device->tag()).cat("': ");
+
+ // if we have a current port, indicate that as well
+ if (m_current_ioport != NULL)
+ string.cat("ioport '").cat(m_current_ioport).cat("': ");
+}
- /* validate inline function behavior */
- error = validate_inlines() || error;
- get_profile_ticks();
+//-------------------------------------------------
+// error_output - error message output override
+//-------------------------------------------------
- /* pre-populate the defstr tagmap with all the default strings */
- prep -= get_profile_ticks();
- for (strnum = 1; strnum < INPUT_STRING_COUNT; strnum++)
- {
- const char *string = input_port_string_from_index(strnum);
- if (string != NULL)
- defstr.add(string, strnum, FALSE);
- }
- prep += get_profile_ticks();
+void validity_checker::error_output(const char *format, va_list argptr)
+{
+ // count the error
+ m_errors++;
+
+ // output the source(driver) device 'tag'
+ astring output;
+ build_output_prefix(output);
+
+ // generate the string
+ output.catvprintf(format, argptr);
+ m_error_text.cat(output);
+}
- /* iterate over all drivers */
- emu_options validation_options(options);
- validation_options.remove_device_options();
- driver_enumerator drivlist(validation_options);
- while (drivlist.next())
- {
- const game_driver &driver = drivlist.driver();
- ioport_list portlist;
- region_array rgninfo;
+//-------------------------------------------------
+// warning_output - warning message output
+// override
+//-------------------------------------------------
- /* non-debug builds only care about games in the same driver */
- if (curdriver != NULL && strcmp(curdriver->source_file, driver.source_file) != 0)
- continue;
+void validity_checker::warning_output(const char *format, va_list argptr)
+{
+ // count the error
+ m_warnings++;
+
+ // output the source(driver) device 'tag'
+ astring output;
+ build_output_prefix(output);
+
+ // generate the string and output to the original target
+ output.catvprintf(format, argptr);
+ m_warning_text.cat(output);
+}
- try
- {
- /* validate the driver entry */
- driver_checks -= get_profile_ticks();
- error = validate_driver(drivlist, names, descriptions) || error;
- driver_checks += get_profile_ticks();
-
- /* validate the ROM information */
- rom_checks -= get_profile_ticks();
- error = validate_roms(drivlist, &rgninfo, roms) || error;
- rom_checks += get_profile_ticks();
-
- /* validate input ports */
- input_checks -= get_profile_ticks();
- error = validate_inputs(drivlist, defstr, portlist) || error;
- input_checks += get_profile_ticks();
-
- /* validate the display */
- display_checks -= get_profile_ticks();
- error = validate_display(drivlist) || error;
- display_checks += get_profile_ticks();
-
- /* validate the graphics decoding */
- gfx_checks -= get_profile_ticks();
- error = validate_gfx(drivlist, &rgninfo) || error;
- gfx_checks += get_profile_ticks();
-
- /* validate devices */
- device_checks -= get_profile_ticks();
- error = validate_devices(drivlist, portlist, &rgninfo) || error;
- error = validate_slots(drivlist) || error;
- device_checks += get_profile_ticks();
- }
- catch (emu_fatalerror &err)
- {
- throw emu_fatalerror("Validating %s (%s): %s", driver.name, driver.source_file, err.string());
- }
- }
-#if (REPORT_TIMES)
- mame_printf_info("Prep: %8dm\n", (int)(prep / 1000000));
- mame_printf_info("Driver: %8dm\n", (int)(driver_checks / 1000000));
- mame_printf_info("ROM: %8dm\n", (int)(rom_checks / 1000000));
- mame_printf_info("CPU: %8dm\n", (int)(cpu_checks / 1000000));
- mame_printf_info("Display: %8dm\n", (int)(display_checks / 1000000));
- mame_printf_info("Graphics: %8dm\n", (int)(gfx_checks / 1000000));
- mame_printf_info("Input: %8dm\n", (int)(input_checks / 1000000));
-#endif
+//-------------------------------------------------
+// output_via_delegate - helper to output a
+// message via a varargs string, so the argptr
+// can be forwarded onto the given delegate
+//-------------------------------------------------
+
+void validity_checker::output_via_delegate(output_delegate &delegate, const char *format, ...)
+{
+ va_list argptr;
- // on a general error, throw rather than return
- if (error)
- throw emu_fatalerror(MAMERR_FAILED_VALIDITY, "Validity checks failed");
+ // call through to the delegate with the proper parameters
+ va_start(argptr, format);
+ delegate(format, argptr);
+ va_end(argptr);
}
diff --git a/src/emu/validity.h b/src/emu/validity.h
index 9864b229e61..d362e155a1e 100644
--- a/src/emu/validity.h
+++ b/src/emu/validity.h
@@ -4,8 +4,36 @@
Validity checks
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
@@ -14,7 +42,94 @@
#ifndef __VALIDITY_H__
#define __VALIDITY_H__
-void validate_drivers(emu_options &options, const game_driver *driver = NULL);
-bool validate_tag(const game_driver &driver, const char *object, const char *tag);
+#include "emu.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// forward declarations
+class machine_config;
+
+
+// core validity checker class
+class validity_checker
+{
+ // internal map types
+ typedef tagmap_t<const game_driver *> game_driver_map;
+ typedef tagmap_t<FPTR> int_map;
+
+public:
+ validity_checker(emu_options &options);
+
+ // getters
+ int errors() const { return m_errors; }
+ int warnings() const { return m_warnings; }
+
+ // operations
+ void check_driver(const game_driver &driver);
+ void check_shared_source(const game_driver &driver);
+ void check_all();
+
+ // helpers for devices
+ void validate_tag(const char *tag);
+
+private:
+ // internal helpers
+ const char *ioport_string_from_index(UINT32 index);
+ int get_defstr_index(const char *string, bool suppress_error = false);
+
+ // core helpers
+ void validate_begin();
+ void validate_end();
+ void validate_one(const game_driver &driver);
+
+ // internal sub-checks
+ void validate_core();
+ void validate_inlines();
+ void validate_driver();
+ void validate_roms();
+ void validate_display();
+ void validate_gfx();
+ void validate_analog_input_field(input_field_config &field);
+ void validate_dip_settings(input_field_config &field);
+ void validate_condition(input_condition &condition, device_t &device, int_map &port_map);
+ void validate_inputs();
+ void validate_devices();
+ void validate_slots();
+
+ // output helpers
+ void build_output_prefix(astring &string);
+ void error_output(const char *format, va_list argptr);
+ void warning_output(const char *format, va_list argptr);
+ void output_via_delegate(output_delegate &delegate, const char *format, ...);
+
+ // internal driver list
+ driver_enumerator m_drivlist;
+
+ // error tracking
+ int m_errors;
+ int m_warnings;
+ astring m_error_text;
+ astring m_warning_text;
+
+ // maps for finding duplicates
+ game_driver_map m_names_map;
+ game_driver_map m_descriptions_map;
+ game_driver_map m_roms_map;
+ int_map m_defstr_map;
+
+ // current state
+ const game_driver * m_current_driver;
+ const machine_config * m_current_config;
+ const device_t * m_current_device;
+ const char * m_current_ioport;
+ int_map m_region_map;
+
+ // callbacks
+ output_delegate m_saved_error_output;
+ output_delegate m_saved_warning_output;
+};
#endif
diff --git a/src/emu/video.c b/src/emu/video.c
index c0514c8e605..e2956bc37ad 100644
--- a/src/emu/video.c
+++ b/src/emu/video.c
@@ -304,7 +304,8 @@ astring &video_manager::speed_text(astring &string)
// display the number of partial updates as well
int partials = 0;
- for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen())
+ screen_device_iterator iter(machine().root_device());
+ for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next())
partials += screen->partial_updates();
if (partials > 1)
string.catprintf("\n%d partial updates", partials);
@@ -355,7 +356,8 @@ void video_manager::save_active_screen_snapshots()
if (m_snap_native)
{
// write one snapshot per visible screen
- for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen())
+ screen_device_iterator iter(machine().root_device());
+ for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next())
if (machine().render().is_live(*screen))
{
emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
@@ -648,12 +650,13 @@ inline int video_manager::original_speed_setting() const
bool video_manager::finish_screen_updates()
{
// finish updating the screens
- for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen())
+ screen_device_iterator iter(machine().root_device());
+ for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next())
screen->update_partial(screen->visible_area().max_y);
// now add the quads for all the screens
bool anything_changed = false;
- for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen())
+ for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next())
if (screen->update_quads())
anything_changed = true;
@@ -663,12 +666,12 @@ bool video_manager::finish_screen_updates()
record_frame();
// iterate over screens and update the burnin for the ones that care
- for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen())
+ for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next())
screen->update_burnin();
}
// draw any crosshairs
- for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen())
+ for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next())
crosshair_render(*screen);
return anything_changed;
@@ -950,7 +953,8 @@ void video_manager::update_refresh_speed()
// find the screen with the shortest frame period (max refresh rate)
// note that we first check the token since this can get called before all screens are created
attoseconds_t min_frame_period = ATTOSECONDS_PER_SECOND;
- for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen())
+ screen_device_iterator iter(machine().root_device());
+ for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next())
{
attoseconds_t period = screen->frame_period().attoseconds;
if (period != 0)
@@ -1047,12 +1051,13 @@ void video_manager::recompute_speed(attotime emutime)
// given screen
//-------------------------------------------------
-void video_manager::create_snapshot_bitmap(device_t *screen)
+void video_manager::create_snapshot_bitmap(screen_device *screen)
{
// select the appropriate view in our dummy target
if (m_snap_native && screen != NULL)
{
- int view_index = machine().devicelist().indexof(SCREEN, screen->tag());
+ screen_device_iterator iter(machine().root_device());
+ int view_index = iter.indexof(*screen);
assert(view_index != -1);
m_snap_target->set_view(view_index);
}
@@ -1135,8 +1140,8 @@ file_error video_manager::open_next(emu_file &file, const char *extension)
//printf("check template: %s\n", snapdevname.cstr());
// verify that there is such a device for this system
- device_image_interface *image = NULL;
- for (bool gotone = machine().devicelist().first(image); gotone; gotone = image->next(image))
+ image_interface_iterator iter(machine().root_device());
+ for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
{
// get the device name
astring tempdevname(image->brief_instance_name());
diff --git a/src/emu/video.h b/src/emu/video.h
index 976274f3835..c6b629dd7d5 100644
--- a/src/emu/video.h
+++ b/src/emu/video.h
@@ -137,7 +137,7 @@ private:
void recompute_speed(attotime emutime);
// snapshot/movie helpers
- void create_snapshot_bitmap(device_t *screen);
+ void create_snapshot_bitmap(screen_device *screen);
file_error open_next(emu_file &file, const char *extension);
void record_frame();
diff --git a/src/emu/video/mc6845.c b/src/emu/video/mc6845.c
index de2cc382ee8..b7faa86ca38 100644
--- a/src/emu/video/mc6845.c
+++ b/src/emu/video/mc6845.c
@@ -766,11 +766,8 @@ void mc6845_device::device_start()
/* get the screen device */
if ( m_screen_tag != NULL )
{
- m_screen = downcast<screen_device *>(machine().device(m_screen_tag));
- if (m_screen == NULL) {
- astring tempstring;
- m_screen = downcast<screen_device *>(machine().device(owner()->subtag(tempstring,m_screen_tag)));
- }
+ astring tempstring;
+ m_screen = downcast<screen_device *>(machine().device(siblingtag(tempstring,m_screen_tag)));
assert(m_screen != NULL);
}
else
diff --git a/src/emu/video/ramdac.c b/src/emu/video/ramdac.c
index 1eea2e8bbf8..61ae67891e5 100644
--- a/src/emu/video/ramdac.c
+++ b/src/emu/video/ramdac.c
@@ -100,10 +100,8 @@ void ramdac_device::device_config_complete()
// on this device
//-------------------------------------------------
-bool ramdac_device::device_validity_check(emu_options &options, const game_driver &driver) const
+void ramdac_device::device_validity_check(validity_checker &valid) const
{
- bool error = false;
- return error;
}
//-------------------------------------------------
diff --git a/src/emu/video/ramdac.h b/src/emu/video/ramdac.h
index 0e53de36b4a..97d28462ce8 100644
--- a/src/emu/video/ramdac.h
+++ b/src/emu/video/ramdac.h
@@ -61,7 +61,7 @@ public:
protected:
// device-level overrides
- virtual bool device_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
virtual void device_config_complete();
diff --git a/src/emu/video/voodoo.c b/src/emu/video/voodoo.c
index 4d554a68909..1e85d8c7617 100644
--- a/src/emu/video/voodoo.c
+++ b/src/emu/video/voodoo.c
@@ -4910,7 +4910,15 @@ static DEVICE_START( voodoo )
}
/* set the type, and initialize the chip mask */
- v->index = device->machine().devicelist().indexof(device->type(), device->tag());
+ device_iterator iter(device->machine().root_device());
+ v->index = 0;
+ for (device_t *scan = iter.first(); scan != NULL; scan = iter.next())
+ if (scan->type() == device->type())
+ {
+ if (scan == device)
+ break;
+ v->index++;
+ }
v->screen = downcast<screen_device *>(device->machine().device(config->screen));
assert_always(v->screen != NULL, "Unable to find screen attached to voodoo");
v->cpu = device->machine().device(config->cputag);
diff --git a/src/lib/lib.mak b/src/lib/lib.mak
index 0daa6225ff9..9eb26d31713 100644
--- a/src/lib/lib.mak
+++ b/src/lib/lib.mak
@@ -208,6 +208,8 @@ $(OBJ)/libsoftfloat.a: $(SOFTFLOATOBJS)
$(LIBOBJ)/softfloat/softfloat.o: $(LIBSRC)/softfloat/softfloat.c $(LIBSRC)/softfloat/softfloat.h $(LIBSRC)/softfloat/softfloat-macros $(LIBSRC)/softfloat/softfloat-specialize
$(LIBOBJ)/softfloat/fsincos.o: $(LIBSRC)/softfloat/fsincos.c $(LIBSRC)/softfloat/fpu_constant.h $(LIBSRC)/softfloat/softfloat.h $(LIBSRC)/softfloat/softfloat-macros $(LIBSRC)/softfloat/softfloat-specialize
+
+
#-------------------------------------------------
# libJPEG library objects
#-------------------------------------------------
@@ -262,7 +264,7 @@ LIBJPEGOBJS= \
$(OBJ)/libjpeg.a: $(LIBJPEGOBJS)
-$(LIBOBJ)/libjpeg/%.o: $(LIBSRC)/libjpeg/%.c
+$(LIBOBJ)/libjpeg/%.o: $(LIBSRC)/libjpeg/%.c | $(OSPREBUILD)
@echo Compiling $<...
$(CC) $(CDEFS) $(CCOMFLAGS) $(CONLYFLAGS) -I$(LIBSRC)/libjpeg -c $< -o $@
@@ -271,6 +273,39 @@ $(LIBOBJ)/libjpeg/%.o: $(LIBSRC)/libjpeg/%.c
# libflac library objects
#-------------------------------------------------
-include $(LIBSRC)/libflac/libflac.mak
-include $(LIBSRC)/libflac/libflac++.mak
+FLACOPTS=-DFLAC__NO_ASM -DHAVE_INTTYPES_H -DHAVE_ICONV -DHAVE_LANGINFO_CODESET -DHAVE_SOCKLEN_T -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
+
+LIBFLACOBJS = \
+ $(LIBOBJ)/libflac/bitmath.o \
+ $(LIBOBJ)/libflac/bitreader.o \
+ $(LIBOBJ)/libflac/bitwriter.o \
+ $(LIBOBJ)/libflac/cpu.o \
+ $(LIBOBJ)/libflac/crc.o \
+ $(LIBOBJ)/libflac/fixed.o \
+ $(LIBOBJ)/libflac/float.o \
+ $(LIBOBJ)/libflac/format.o \
+ $(LIBOBJ)/libflac/lpc.o \
+ $(LIBOBJ)/libflac/md5.o \
+ $(LIBOBJ)/libflac/memory.o \
+ $(LIBOBJ)/libflac/stream_decoder.o \
+ $(LIBOBJ)/libflac/stream_encoder.o \
+ $(LIBOBJ)/libflac/stream_encoder_framing.o \
+ $(LIBOBJ)/libflac/window.o
+
+$(OBJ)/libflac.a: $(LIBFLACOBJS)
+
+$(LIBOBJ)/libflac/%.o: $(LIBSRC)/libflac/libflac/%.c | $(OSPREBUILD)
+ @echo Compiling $<...
+ $(CC) $(CDEFS) $(FLACOPTS) $(CONLYFLAGS) -I$(LIBSRC)/libflac/include -c $< -o $@
+
+LIBFLACPPOBJS = \
+ $(LIBOBJ)/libflacpp/metadata.o \
+ $(LIBOBJ)/libflacpp/stream_decoder.o \
+ $(LIBOBJ)/libflacpp/stream_encoder.o
+
+$(OBJ)/libflac++.a: $(LIBFLACPPOBJS)
+
+$(LIBOBJ)/libflacpp/%.o: $(LIBSRC)/libflac/libflac++/%.cpp | $(OSPREBUILD)
+ @echo Compiling $<...
+ $(CC) $(CDEFS) $(FLACOPTS) $(CPPONLYFLAGS) -I$(LIBSRC)/libflac/include -c $< -o $@
diff --git a/src/lib/libflac/include/flac/ordinals.h b/src/lib/libflac/include/flac/ordinals.h
index a7a5cd96135..96ed4f8961f 100644
--- a/src/lib/libflac/include/flac/ordinals.h
+++ b/src/lib/libflac/include/flac/ordinals.h
@@ -77,4 +77,7 @@ typedef FLAC__uint8 FLAC__byte;
#define false 0
#endif
+// MAME addition -- seems lame to make this a command-line parameter
+#define VERSION "1.2.1"
+
#endif
diff --git a/src/lib/libflac/libflac++.mak b/src/lib/libflac/libflac++.mak
deleted file mode 100644
index cad547df205..00000000000
--- a/src/lib/libflac/libflac++.mak
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-DEFINES = -DFLAC__NO_ASM -DFLAC__ALIGN_MALLOC_DATA
-
-INCLUDES = -I./include -I$(LIBSRC)/libflac/include
-
-LIBFLACPPOBJS = \
- $(LIBOBJ)/libflacpp/metadata.o \
- $(LIBOBJ)/libflacpp/stream_decoder.o \
- $(LIBOBJ)/libflacpp/stream_encoder.o
-
-
-VERSION=\"1.2.1\"
-CONFIG_CFLAGS=-DHAVE_INTTYPES_H -DHAVE_ICONV -DFLAC__NO_ASM -D__MINGW32__ -DHAVE_LANGINFO_CODESET -DHAVE_SOCKLEN_T -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
-LIBFLACPPCFLAGS = -O3 -fomit-frame-pointer -funroll-loops -finline-functions -DNDEBUG $(CONFIG_CFLAGS) $(RELEASE_CFLAGS) -DFLaC__INLINE=__inline__ -DVERSION=$(VERSION) $(DEFINES) $(INCLUDES)
-
-$(LIBOBJ)/libflacpp/%.o: $(LIBSRC)/libflac/libflac++/%.cpp
- @echo Compiling $<...
- $(CC) $(CDEFS) $(LIBFLACPPCFLAGS) $(CPPONLYFLAGS) -c $< -o $@
-
-
-$(OBJ)/libflac++.a: $(LIBFLACPPOBJS)
diff --git a/src/lib/libflac/libflac.mak b/src/lib/libflac/libflac.mak
deleted file mode 100644
index 0e1c6ee7c1c..00000000000
--- a/src/lib/libflac/libflac.mak
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-DEFINES = -DFLAC__NO_ASM -DFLAC__ALIGN_MALLOC_DATA
-
-INCLUDES = -I./include -I$(LIBSRC)/libflac/include
-
-LIBFLACOBJS = \
- $(LIBOBJ)/libflac/bitmath.o \
- $(LIBOBJ)/libflac/bitreader.o \
- $(LIBOBJ)/libflac/bitwriter.o \
- $(LIBOBJ)/libflac/cpu.o \
- $(LIBOBJ)/libflac/crc.o \
- $(LIBOBJ)/libflac/fixed.o \
- $(LIBOBJ)/libflac/float.o \
- $(LIBOBJ)/libflac/format.o \
- $(LIBOBJ)/libflac/lpc.o \
- $(LIBOBJ)/libflac/md5.o \
- $(LIBOBJ)/libflac/memory.o \
- $(LIBOBJ)/libflac/stream_decoder.o \
- $(LIBOBJ)/libflac/stream_encoder.o \
- $(LIBOBJ)/libflac/stream_encoder_framing.o \
- $(LIBOBJ)/libflac/window.o
-
-VERSION=\"1.2.1\"
-CONFIG_CFLAGS=-DHAVE_INTTYPES_H -DHAVE_ICONV -DFLAC__NO_ASM -D__MINGW32__ -DHAVE_LANGINFO_CODESET -DHAVE_SOCKLEN_T -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
-LIBFLACCFLAGS = -O3 -fomit-frame-pointer -funroll-loops -finline-functions -DNDEBUG $(CONFIG_CFLAGS) $(RELEASE_CFLAGS) -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -DFLaC__INLINE=__inline__ -DVERSION=$(VERSION) $(DEFINES) $(INCLUDES)
-
-$(LIBOBJ)/libflac/%.o: $(LIBSRC)/libflac/libflac/%.c
- @echo Compiling $<...
- $(CC) $(CDEFS) $(LIBFLACCFLAGS) $(CONLYFLAGS) -c $< -o $@
-
-
-$(OBJ)/libflac.a: $(LIBFLACOBJS)
diff --git a/src/mame/drivers/cliffhgr.c b/src/mame/drivers/cliffhgr.c
index 68cb24302b9..28c44cc6373 100644
--- a/src/mame/drivers/cliffhgr.c
+++ b/src/mame/drivers/cliffhgr.c
@@ -708,7 +708,6 @@ static MACHINE_CONFIG_START( cliffhgr, cliffhgr_state )
MCFG_TMS9928A_ADD( "tms9928a", TMS9128, cliffhgr_tms9928a_interface ) /* TMS9128NL on the board */
/* override video rendering and raw screen info */
- MCFG_DEVICE_REMOVE("screen")
MCFG_LASERDISC_SCREEN_ADD_NTSC("screen", "laserdisc")
/* sound hardware */
diff --git a/src/mame/drivers/firebeat.c b/src/mame/drivers/firebeat.c
index f74faa16919..d7645414153 100644
--- a/src/mame/drivers/firebeat.c
+++ b/src/mame/drivers/firebeat.c
@@ -646,7 +646,8 @@ static void GCU_w(running_machine &machine, int chip, UINT32 offset, UINT32 data
COMBINE_DATA( &state->m_gcu[chip].visible_area );
if (ACCESSING_BITS_0_15)
{
- screen_device *screen = downcast<screen_device *>(machine.devicelist().find(SCREEN, chip));
+ screen_device_iterator iter(machine.root_device());
+ screen_device *screen = iter.byindex(chip);
if (screen != NULL)
{
diff --git a/src/mame/drivers/merit.c b/src/mame/drivers/merit.c
index fbe5ea6e5b5..344c984540a 100644
--- a/src/mame/drivers/merit.c
+++ b/src/mame/drivers/merit.c
@@ -1266,7 +1266,7 @@ static MACHINE_CONFIG_DERIVED( dodge, pitboss )
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(dodge_map)
- MCFG_NVRAM_REPLACE_CUSTOM_DRIVER("nvram", merit_state, dodge_nvram_init)
+ MCFG_NVRAM_ADD_CUSTOM_DRIVER("nvram", merit_state, dodge_nvram_init)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( tictac, pitboss )
diff --git a/src/mame/drivers/pinkiri8.c b/src/mame/drivers/pinkiri8.c
index 7ce47431dea..291549fe535 100644
--- a/src/mame/drivers/pinkiri8.c
+++ b/src/mame/drivers/pinkiri8.c
@@ -86,7 +86,7 @@ public:
janshi_vdp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
protected:
virtual void device_config_complete();
- virtual bool device_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
@@ -109,10 +109,8 @@ void janshi_vdp_device::device_config_complete()
// m_space_config = address_space_config("janshi_vdp", ENDIANNESS_BIG, 8, address_bits, 0, *ADDRESS_MAP_NAME(janshi_vdp_map8));
}
-bool janshi_vdp_device::device_validity_check(emu_options &options, const game_driver &driver) const
+void janshi_vdp_device::device_validity_check(validity_checker &valid) const
{
- bool error = false;
- return error;
}
void janshi_vdp_device::device_start()
diff --git a/src/mame/etc/template_device.c b/src/mame/etc/template_device.c
index 472812d7334..b8489ed998a 100644
--- a/src/mame/etc/template_device.c
+++ b/src/mame/etc/template_device.c
@@ -37,12 +37,11 @@ xxx_device::xxx_device(const machine_config &mconfig, const char *tag, device_t
// on this device
//-------------------------------------------------
-bool xxx_device::device_validity_check(emu_options &options, const game_driver &driver) const
+void xxx_device::device_validity_check(validity_checker &valid) const
{
- bool error = false;
- return error;
}
+
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
diff --git a/src/mame/etc/template_device.h b/src/mame/etc/template_device.h
index 8a4ddab875a..b8642d827f9 100644
--- a/src/mame/etc/template_device.h
+++ b/src/mame/etc/template_device.h
@@ -37,7 +37,7 @@ public:
protected:
// device-level overrides
- virtual bool device_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
};
diff --git a/src/mame/machine/atarigen.c b/src/mame/machine/atarigen.c
index 5b56dfa838d..ad90b382a03 100644
--- a/src/mame/machine/atarigen.c
+++ b/src/mame/machine/atarigen.c
@@ -116,8 +116,9 @@ void atarigen_init(running_machine &machine)
int i;
/* allocate timers for all screens */
- assert(machine.devicelist().count(SCREEN) <= ARRAY_LENGTH(state->m_screen_timer));
- for (i = 0, screen = machine.first_screen(); screen != NULL; i++, screen = screen->next_screen())
+ screen_device_iterator iter(machine.root_device());
+ assert(iter.count() < ARRAY_LENGTH(state->m_screen_timer));
+ for (i = 0, screen = iter.first(); screen != NULL; i++, screen = iter.next())
{
state->m_screen_timer[i].screen = screen;
state->m_screen_timer[i].scanline_interrupt_timer = machine.scheduler().timer_alloc(FUNC(scanline_interrupt_callback), (void *)screen);
@@ -838,8 +839,8 @@ static TIMER_CALLBACK( delayed_6502_sound_w )
void atarigen_set_vol(running_machine &machine, int volume, device_type type)
{
- device_sound_interface *sound = NULL;
- for (bool gotone = machine.devicelist().first(sound); gotone; gotone = sound->next(sound))
+ sound_interface_iterator iter(machine.root_device());
+ for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next())
if (sound->device().type() == type)
sound->set_output_gain(ALL_OUTPUTS, volume / 100.0);
}
diff --git a/src/mame/machine/mie.c b/src/mame/machine/mie.c
index f7ca6ef4bc9..fd07a18b9ef 100644
--- a/src/mame/machine/mie.c
+++ b/src/mame/machine/mie.c
@@ -100,7 +100,7 @@ IRQ_CALLBACK(mie_device::irq_callback_1)
void mie_device::device_start()
{
maple_device::device_start();
- cpu = downcast<z80_device *>(subdevice("mie"));
+ cpu = subdevice<z80_device>("mie");
timer = timer_alloc(0);
cpu->set_irq_callback(irq_callback_1);
jvs = machine().device<mie_jvs_device>(jvs_name);
diff --git a/src/mame/machine/psx.c b/src/mame/machine/psx.c
index eb100474c18..6c779c50201 100644
--- a/src/mame/machine/psx.c
+++ b/src/mame/machine/psx.c
@@ -51,19 +51,19 @@ READ32_HANDLER( psx_com_delay_r )
void psx_irq_set( running_machine &machine, UINT32 data )
{
- psxcpu_device::irq_set( *machine.device("maincpu"), "maincpu", data );
+ psxcpu_device::irq_set( *machine.device("maincpu^"), "maincpu", data );
}
/* SIO */
void psx_sio_install_handler( running_machine &machine, int n_port, psx_sio_handler p_f_sio_handler )
{
- psxcpu_device::install_sio_handler( *machine.device("maincpu"), "maincpu", n_port, p_f_sio_handler );
+ psxcpu_device::install_sio_handler( *machine.device("maincpu^"), "maincpu", n_port, p_f_sio_handler );
}
void psx_sio_input( running_machine &machine, int n_port, int n_mask, int n_data )
{
- psxcpu_device::sio_input( *machine.device("maincpu"), "maincpu", n_port, n_mask, n_data );
+ psxcpu_device::sio_input( *machine.device("maincpu^"), "maincpu", n_port, n_mask, n_data );
}
/* GPU */
diff --git a/src/mame/video/cyberbal.c b/src/mame/video/cyberbal.c
index ec9209e6e49..e82cb590bfb 100644
--- a/src/mame/video/cyberbal.c
+++ b/src/mame/video/cyberbal.c
@@ -267,7 +267,8 @@ void cyberbal_scanline_update(screen_device &screen, int scanline)
screen_device *update_screen;
/* loop over screens */
- for (i = 0, update_screen = screen.machine().first_screen(); update_screen != NULL; i++, update_screen = update_screen->next_screen())
+ screen_device_iterator iter(screen.machine().root_device());
+ for (i = 0, update_screen = iter.first(); update_screen != NULL; i++, update_screen = iter.next())
{
UINT16 *vram = i ? state->m_alpha2 : state->m_alpha;
UINT16 *base = &vram[((scanline - 8) / 8) * 64 + 47];
diff --git a/src/mame/video/gp9001.c b/src/mame/video/gp9001.c
index 6e2433559c3..55e07888bf3 100644
--- a/src/mame/video/gp9001.c
+++ b/src/mame/video/gp9001.c
@@ -224,10 +224,8 @@ void gp9001vdp_device::static_set_gfx_region(device_t &device, int gfxregion)
vdp.m_gfxregion = gfxregion;
}
-bool gp9001vdp_device::device_validity_check(emu_options &options, const game_driver &driver) const
+void gp9001vdp_device::device_validity_check(validity_checker &valid) const
{
- bool error = false;
- return error;
}
const address_space_config *gp9001vdp_device::memory_space_config(address_spacenum spacenum) const
diff --git a/src/mame/video/gp9001.h b/src/mame/video/gp9001.h
index abaa1c8ff33..a981668dc65 100644
--- a/src/mame/video/gp9001.h
+++ b/src/mame/video/gp9001.h
@@ -64,7 +64,7 @@ public:
bitmap_ind8 *custom_priority_bitmap;
protected:
- virtual bool device_validity_check(emu_options &options, const game_driver &driver) const;
+ virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
diff --git a/src/osd/sdl/drawogl.c b/src/osd/sdl/drawogl.c
index 4f4e2cbecbf..2ce2e4299cc 100644
--- a/src/osd/sdl/drawogl.c
+++ b/src/osd/sdl/drawogl.c
@@ -1206,7 +1206,8 @@ static int drawogl_window_draw(sdl_window_info *window, UINT32 dc, int update)
// figure out if we're vector
scrnum = is_vector = 0;
- for (screen = window->machine().config().first_screen(); screen != NULL; screen = screen->next_screen())
+ screen_device_iterator iter(window->machine().root_device());
+ for (screen = iter.first(); screen != NULL; screen = iter.next())
{
if (scrnum == window->index)
{
@@ -2950,7 +2951,8 @@ static void texture_shader_update(sdl_window_info *window, texture_info *texture
scrnum = 0;
container = (render_container *)NULL;
- for (screen_device *screen = window->machine().first_screen(); screen != NULL; screen = screen->next_screen())
+ screen_device_iterator iter(window->machine().root_device());
+ for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next())
{
if (scrnum == window->start_viewscreen)
{
diff --git a/src/osd/windows/d3dhlsl.c b/src/osd/windows/d3dhlsl.c
index fc8f53e1302..ee0841ce563 100644
--- a/src/osd/windows/d3dhlsl.c
+++ b/src/osd/windows/d3dhlsl.c
@@ -1928,14 +1928,8 @@ int hlsl_info::register_prescaled_texture(d3d_texture_info *texture, int scwidth
//============================================================
void hlsl_info::enumerate_screens()
{
- screen_device *screen = window->machine().first_screen();
- num_screens = 0;
- while(screen != NULL)
- {
- num_screens++;
- screen = screen->next_screen();
- //printf("Encountered %d screens\n", num_screens);
- }
+ screen_device_iterator iter(window->machine().root_device());
+ num_screens = iter.count();
}
//============================================================
@@ -2792,8 +2786,8 @@ static file_error open_next(d3d_info *d3d, emu_file &file, const char *templ, co
snapdevname.cpysubstr(snapstr, pos + 3, end - pos - 3);
// verify that there is such a device for this system
- device_image_interface *image = NULL;
- for (bool gotone = d3d->window->machine().devicelist().first(image); gotone; gotone = image->next(image))
+ image_interface_iterator iter(d3d->window->machine().root_device());
+ for (device_image_interface *image = iter.first(); image != NULL; iter.next())
{
// get the device name
astring tempdevname(image->brief_instance_name());
diff --git a/src/osd/windows/debugwin.c b/src/osd/windows/debugwin.c
index e7a50015670..1c308aa9de0 100644
--- a/src/osd/windows/debugwin.c
+++ b/src/osd/windows/debugwin.c
@@ -2399,7 +2399,6 @@ enum
static void image_update_menu(debugwin_info *info)
{
- device_image_interface *img = NULL;
UINT32 cnt = 0;
HMENU devicesmenu;
@@ -2407,7 +2406,8 @@ static void image_update_menu(debugwin_info *info)
// create the image menu
devicesmenu = CreatePopupMenu();
- for (bool gotone = info->machine().devicelist().first(img); gotone; gotone = img->next(img))
+ image_interface_iterator iter(info->machine().root_device());
+ for (device_image_interface *img = iter.first(); img != NULL; img = iter.next())
{
astring temp;
UINT flags_for_exists;
@@ -2465,7 +2465,6 @@ void console_create_window(running_machine &machine)
RECT bounds, work_bounds;
HMENU optionsmenu;
UINT32 conchars;
- device_image_interface *img = NULL;
// create the window
info = debugwin_window_create(machine, "Debug", NULL);
@@ -2492,9 +2491,12 @@ void console_create_window(running_machine &machine)
AppendMenu(GetMenu(info->wnd), MF_ENABLED | MF_POPUP, (UINT_PTR)optionsmenu, TEXT("Options"));
// Add image menu only if image devices exist
- if (info->machine().devicelist().first(img)) {
- info->update_menu = image_update_menu;
- image_update_menu(info);
+ {
+ image_interface_iterator iter(machine.root_device());
+ if (iter.first() != NULL) {
+ info->update_menu = image_update_menu;
+ image_update_menu(info);
+ }
}
// set the handlers
@@ -2888,13 +2890,8 @@ static int global_handle_command(debugwin_info *info, WPARAM wparam, LPARAM lpar
}
if (LOWORD(wparam) >= ID_DEVICE_OPTIONS) {
UINT32 devid = (LOWORD(wparam) - ID_DEVICE_OPTIONS) / DEVOPTION_MAX;
- device_image_interface *img = NULL;
- UINT32 cnt = 0;
- for (bool gotone = info->machine().devicelist().first(img); gotone; gotone = img->next(img))
- {
- if (cnt==devid) break;
- cnt++;
- }
+ image_interface_iterator iter(info->machine().root_device());
+ device_image_interface *img = iter.byindex(devid);
if (img!=NULL) {
switch ((LOWORD(wparam) - ID_DEVICE_OPTIONS) % DEVOPTION_MAX)
{
diff --git a/src/osd/windows/winmain.c b/src/osd/windows/winmain.c
index 66056e7d539..4da69ce1921 100644
--- a/src/osd/windows/winmain.c
+++ b/src/osd/windows/winmain.c
@@ -283,7 +283,7 @@ static BOOL WINAPI control_handler(DWORD type);
static int is_double_click_start(int argc);
static DWORD WINAPI watchdog_thread_entry(LPVOID lpParameter);
static LONG WINAPI exception_filter(struct _EXCEPTION_POINTERS *info);
-static void winui_output_error(void *param, const char *format, va_list argptr);
+static void winui_output_error(delegate_late_bind *__dummy, const char *format, va_list argptr);
@@ -467,7 +467,7 @@ int main(int argc, char *argv[])
if (win_is_gui_application() || is_double_click_start(argc))
{
// if we are a GUI app, output errors to message boxes
- mame_set_output_channel(OUTPUT_CHANNEL_ERROR, winui_output_error, NULL, NULL, NULL);
+ mame_set_output_channel(OUTPUT_CHANNEL_ERROR, output_delegate(FUNC(winui_output_error), (delegate_late_bind *)0));
// make sure any console window that opened on our behalf is nuked
FreeConsole();
@@ -539,7 +539,7 @@ static BOOL WINAPI control_handler(DWORD type)
// winui_output_error
//============================================================
-static void winui_output_error(void *param, const char *format, va_list argptr)
+static void winui_output_error(delegate_late_bind *param, const char *format, va_list argptr)
{
char buffer[1024];