diff options
Diffstat (limited to 'src/emu/devfind.cpp')
-rw-r--r-- | src/emu/devfind.cpp | 411 |
1 files changed, 292 insertions, 119 deletions
diff --git a/src/emu/devfind.cpp b/src/emu/devfind.cpp index 4128123e0f2..6170b2fca8c 100644 --- a/src/emu/devfind.cpp +++ b/src/emu/devfind.cpp @@ -2,94 +2,39 @@ // copyright-holders:Aaron Giles /*************************************************************************** - devfind.c + devfind.cpp Device finding template helpers. ***************************************************************************/ #include "emu.h" + #include "romload.h" +#include "validity.h" //************************************************************************** -// EXPLICIT TEMPLATE INSTANTIATIONS +// BASE FINDER CLASS //************************************************************************** -template class object_finder_base<memory_region, false>; -template class object_finder_base<memory_region, true>; -template class object_finder_base<memory_bank, false>; -template class object_finder_base<memory_bank, true>; -template class object_finder_base<ioport_port, false>; -template class object_finder_base<ioport_port, true>; -template class object_finder_base<address_space, false>; -template class object_finder_base<address_space, true>; - -template class object_finder_base<u8, false>; -template class object_finder_base<u8, true>; -template class object_finder_base<u16, false>; -template class object_finder_base<u16, true>; -template class object_finder_base<u32, false>; -template class object_finder_base<u32, true>; -template class object_finder_base<u64, false>; -template class object_finder_base<u64, true>; - -template class object_finder_base<s8, false>; -template class object_finder_base<s8, true>; -template class object_finder_base<s16, false>; -template class object_finder_base<s16, true>; -template class object_finder_base<s32, false>; -template class object_finder_base<s32, true>; -template class object_finder_base<s64, false>; -template class object_finder_base<s64, true>; - -template class memory_region_finder<false>; -template class memory_region_finder<true>; - -template class memory_bank_finder<false>; -template class memory_bank_finder<true>; - -template class ioport_finder<false>; -template class ioport_finder<true>; - -template class address_space_finder<false>; -template class address_space_finder<true>; +//------------------------------------------------- +// device_resolver_base - constructor +//------------------------------------------------- -template class region_ptr_finder<u8, false>; -template class region_ptr_finder<u8, true>; -template class region_ptr_finder<u16, false>; -template class region_ptr_finder<u16, true>; -template class region_ptr_finder<u32, false>; -template class region_ptr_finder<u32, true>; -template class region_ptr_finder<u64, false>; -template class region_ptr_finder<u64, true>; +device_resolver_base::device_resolver_base(device_t &base) + : m_next(base.register_auto_finder(*this)) +{ +} -template class region_ptr_finder<s8, false>; -template class region_ptr_finder<s8, true>; -template class region_ptr_finder<s16, false>; -template class region_ptr_finder<s16, true>; -template class region_ptr_finder<s32, false>; -template class region_ptr_finder<s32, true>; -template class region_ptr_finder<s64, false>; -template class region_ptr_finder<s64, true>; -template class shared_ptr_finder<u8, false>; -template class shared_ptr_finder<u8, true>; -template class shared_ptr_finder<u16, false>; -template class shared_ptr_finder<u16, true>; -template class shared_ptr_finder<u32, false>; -template class shared_ptr_finder<u32, true>; -template class shared_ptr_finder<u64, false>; -template class shared_ptr_finder<u64, true>; +//------------------------------------------------- +// ~device_resolver_base - destructor +//------------------------------------------------- -template class shared_ptr_finder<s8, false>; -template class shared_ptr_finder<s8, true>; -template class shared_ptr_finder<s16, false>; -template class shared_ptr_finder<s16, true>; -template class shared_ptr_finder<s32, false>; -template class shared_ptr_finder<s32, true>; -template class shared_ptr_finder<s64, false>; -template class shared_ptr_finder<s64, true>; +device_resolver_base::~device_resolver_base() +{ +} @@ -105,7 +50,7 @@ constexpr char finder_base::DUMMY_TAG[]; //------------------------------------------------- finder_base::finder_base(device_t &base, char const *tag) - : m_next(base.register_auto_finder(*this)) + : device_resolver_base(base) , m_base(base) , m_tag(tag) , m_resolved(false) @@ -114,21 +59,13 @@ finder_base::finder_base(device_t &base, char const *tag) //------------------------------------------------- -// ~finder_base - destructor -//------------------------------------------------- - -finder_base::~finder_base() -{ -} - - -//------------------------------------------------- // set_tag - set tag //------------------------------------------------- void finder_base::set_tag(char const *tag) { assert(!m_resolved); + assert(tag); m_base = m_base.get().mconfig().current_device(); m_tag = tag; } @@ -152,23 +89,13 @@ void *finder_base::find_memregion(u8 width, size_t &length, bool required) const if (region->bytewidth() != width) { if (required) - osd_printf_warning("Region '%s' found but is width %d, not %d as requested\n", m_tag, region->bitwidth(), width*8); - length = 0; - return nullptr; - } - - // check the length and warn if other than specified - size_t const length_found = region->bytes() / width; - if (length != 0 && length != length_found) - { - if (required) - osd_printf_warning("Region '%s' found but has %d bytes, not %ld as requested\n", m_tag, region->bytes(), long(length*width)); + osd_printf_warning("Region '%s' found but is width %d, not %d as requested\n", m_tag, region->bitwidth(), width * 8); length = 0; return nullptr; } // return results - length = length_found; + length = region->bytes() / width; return region->base(); } @@ -177,14 +104,14 @@ void *finder_base::find_memregion(u8 width, size_t &length, bool required) const // validate_memregion - find memory region //------------------------------------------------- -bool finder_base::validate_memregion(size_t bytes, bool required) const +bool finder_base::validate_memregion(bool required) const { // make sure we can resolve the full path to the region size_t bytes_found = 0; std::string const region_fulltag(m_base.get().subtag(m_tag)); // look for the region - for (device_t const &dev : device_iterator(m_base.get().mconfig().root_device())) + for (device_t const &dev : device_enumerator(m_base.get().mconfig().root_device())) { for (romload::region const ®ion : romload::entries(dev.rom_region()).get_regions()) { @@ -198,13 +125,6 @@ bool finder_base::validate_memregion(size_t bytes, bool required) const break; } - // check the length and warn if other than specified - if ((bytes_found != 0) && (bytes != 0) && (bytes != bytes_found)) - { - osd_printf_warning("Region '%s' found but has %ld bytes, not %ld as requested\n", m_tag, long(bytes_found), long(bytes)); - bytes_found = 0; - } - return report_missing(bytes_found != 0, "memory region", required); } @@ -223,8 +143,7 @@ void *finder_base::find_memshare(u8 width, size_t &bytes, bool required) const // check the width and warn if not correct if (width != 0 && share->bitwidth() != width) { - if (required) - osd_printf_warning("Shared ptr '%s' found but is width %d, not %d as requested\n", m_tag, share->bitwidth(), width); + osd_printf_warning("Shared ptr '%s' found but is width %d, not %d as requested\n", m_tag, share->bitwidth(), width); return nullptr; } @@ -264,8 +183,7 @@ address_space *finder_base::find_addrspace(int spacenum, u8 width, bool required address_space &space(memory->space(spacenum)); if (width != 0 && width != space.data_width()) { - if (required) - osd_printf_warning("Device '%s' found but address space #%d has the wrong data width (expected %d, found %d)\n", m_tag, spacenum, width, space.data_width()); + osd_printf_warning("Device '%s' found but address space #%d has the wrong data width (expected %d, found %d)\n", m_tag, spacenum, width, space.data_width()); return nullptr; } @@ -282,7 +200,7 @@ bool finder_base::validate_addrspace(int spacenum, u8 width, bool required) cons { // look up the device and return false if not found device_t *const device(m_base.get().subdevice(m_tag)); - if (device == nullptr) + if (!device) return report_missing(false, "address space", required); // check for memory interface and a configuration for the designated space @@ -329,22 +247,277 @@ bool finder_base::report_missing(bool found, const char *objname, bool required) // otherwise, report std::string const region_fulltag(m_base.get().subtag(m_tag)); if (required) - osd_printf_error("Required %s '%s' not found\n", objname, region_fulltag.c_str()); + osd_printf_error("Required %s '%s' not found\n", objname, region_fulltag); else if (DUMMY_TAG != m_tag) - osd_printf_verbose("Optional %s '%s' not found\n", objname, region_fulltag.c_str()); + osd_printf_verbose("Optional %s '%s' not found\n", objname, region_fulltag); return !required; } } -void finder_base::printf_warning(const char *format, ...) + +//************************************************************************** +// MEMORY REGION FINDER +//************************************************************************** + +template <bool Required> +memory_region_finder<Required>::memory_region_finder(device_t &base, char const *tag) + : object_finder_base<memory_region, Required>(base, tag) +{ +} + + +template <bool Required> +bool memory_region_finder<Required>::findit(validity_checker *valid) +{ + if (valid) + return this->validate_memregion(Required); + + assert(!this->m_resolved); + this->m_resolved = true; + this->m_target = this->m_base.get().memregion(this->m_tag); + return this->report_missing("memory region"); +} + + + +//************************************************************************** +// MEMORY BANK FINDER +//************************************************************************** + +template <bool Required> +memory_bank_finder<Required>::memory_bank_finder(device_t &base, char const *tag) + : object_finder_base<memory_bank, Required>(base, tag) +{ +} + + +template <bool Required> +bool memory_bank_finder<Required>::findit(validity_checker *valid) { - va_list argptr; - char buffer[1024]; - - // do the output - va_start(argptr, format); - vsnprintf(buffer, 1024, format, argptr); - osd_printf_warning("%s", buffer); - va_end(argptr); + if (valid) + return true; + + assert(!this->m_resolved); + this->m_resolved = true; + this->m_target = this->m_base.get().membank(this->m_tag); + return this->report_missing("memory bank"); } + + + +//************************************************************************** +// I/O PORT FINDER +//************************************************************************** + +template <bool Required> +ioport_finder<Required>::ioport_finder(device_t &base, char const *tag) + : object_finder_base<ioport_port, Required>(base, tag) +{ +} + + +template <bool Required> +bool ioport_finder<Required>::findit(validity_checker *valid) +{ + if (valid) + return finder_base::report_missing(!valid->ioport_missing(this->m_base.get().subtag(this->m_tag).c_str()), "I/O port", Required); + + assert(!this->m_resolved); + this->m_resolved = true; + this->m_target = this->m_base.get().ioport(this->m_tag); + return this->report_missing("I/O port"); +} + + + +//************************************************************************** +// ADDRESS SPACE FINDER +//************************************************************************** + +template <bool Required> +address_space_finder<Required>::address_space_finder(device_t &base, char const *tag, int spacenum, u8 width) + : object_finder_base<address_space, Required>(base, tag) + , m_spacenum(spacenum) + , m_data_width(width) +{ +} + + +template <bool Required> +bool address_space_finder<Required>::findit(validity_checker *valid) +{ + if (valid) + return this->validate_addrspace(this->m_spacenum, this->m_data_width, Required); + + assert(!this->m_resolved); + this->m_resolved = true; + this->m_target = this->find_addrspace(this->m_spacenum, this->m_data_width, Required); + return this->report_missing("address space"); +} + + + +//************************************************************************** +// MEMORY BANK CREATOR +//************************************************************************** + +bool memory_bank_creator::findit(validity_checker *valid) +{ + if (valid) + return true; + + device_t &dev = m_base.get(); + memory_manager &manager = dev.machine().memory(); + std::string const tag = dev.subtag(m_tag); + memory_bank *const bank = manager.bank_find(tag); + m_target = bank ? bank : manager.bank_alloc(dev, tag); + return true; +} + + +void memory_bank_creator::end_configuration() +{ + m_target = nullptr; +} + + + +//************************************************************************** +// MEMORY SHARE CREATOR +//************************************************************************** + +template <typename PointerType> +memory_share_creator<PointerType>::memory_share_creator(device_t &base, char const *tag, size_t bytes, endianness_t endianness) + : finder_base(base, tag) + , m_width(sizeof(PointerType) * 8) + , m_bytes(bytes) + , m_endianness(endianness) +{ +} + + +template <typename PointerType> +bool memory_share_creator<PointerType>::findit(validity_checker *valid) +{ + if (valid) + return true; + + device_t &dev = m_base.get(); + memory_manager &manager = dev.machine().memory(); + std::string const tag = dev.subtag(m_tag); + memory_share *const share = manager.share_find(tag); + if (share) + { + std::string const result = share->compare(m_width, m_bytes, m_endianness); + if (!result.empty()) + { + osd_printf_error("%s\n", result); + return false; + } + m_target = share; + } + else + { + m_target = manager.share_alloc(dev, tag, m_width, m_bytes, m_endianness); + } + return true; +} + + +template <typename PointerType> +void memory_share_creator<PointerType>::end_configuration() +{ + m_target = nullptr; +} + + + +//************************************************************************** +// EXPLICIT TEMPLATE INSTANTIATIONS +//************************************************************************** + +template class object_finder_base<memory_region, false>; +template class object_finder_base<memory_region, true>; +template class object_finder_base<memory_bank, false>; +template class object_finder_base<memory_bank, true>; +template class object_finder_base<ioport_port, false>; +template class object_finder_base<ioport_port, true>; +template class object_finder_base<address_space, false>; +template class object_finder_base<address_space, true>; + +template class object_finder_base<u8, false>; +template class object_finder_base<u8, true>; +template class object_finder_base<u16, false>; +template class object_finder_base<u16, true>; +template class object_finder_base<u32, false>; +template class object_finder_base<u32, true>; +template class object_finder_base<u64, false>; +template class object_finder_base<u64, true>; + +template class object_finder_base<s8, false>; +template class object_finder_base<s8, true>; +template class object_finder_base<s16, false>; +template class object_finder_base<s16, true>; +template class object_finder_base<s32, false>; +template class object_finder_base<s32, true>; +template class object_finder_base<s64, false>; +template class object_finder_base<s64, true>; + +template class memory_region_finder<false>; +template class memory_region_finder<true>; + +template class memory_bank_finder<false>; +template class memory_bank_finder<true>; + +template class ioport_finder<false>; +template class ioport_finder<true>; + +template class address_space_finder<false>; +template class address_space_finder<true>; + +template class region_ptr_finder<u8, false>; +template class region_ptr_finder<u8, true>; +template class region_ptr_finder<u16, false>; +template class region_ptr_finder<u16, true>; +template class region_ptr_finder<u32, false>; +template class region_ptr_finder<u32, true>; +template class region_ptr_finder<u64, false>; +template class region_ptr_finder<u64, true>; + +template class region_ptr_finder<s8, false>; +template class region_ptr_finder<s8, true>; +template class region_ptr_finder<s16, false>; +template class region_ptr_finder<s16, true>; +template class region_ptr_finder<s32, false>; +template class region_ptr_finder<s32, true>; +template class region_ptr_finder<s64, false>; +template class region_ptr_finder<s64, true>; + +template class shared_ptr_finder<u8, false>; +template class shared_ptr_finder<u8, true>; +template class shared_ptr_finder<u16, false>; +template class shared_ptr_finder<u16, true>; +template class shared_ptr_finder<u32, false>; +template class shared_ptr_finder<u32, true>; +template class shared_ptr_finder<u64, false>; +template class shared_ptr_finder<u64, true>; + +template class shared_ptr_finder<s8, false>; +template class shared_ptr_finder<s8, true>; +template class shared_ptr_finder<s16, false>; +template class shared_ptr_finder<s16, true>; +template class shared_ptr_finder<s32, false>; +template class shared_ptr_finder<s32, true>; +template class shared_ptr_finder<s64, false>; +template class shared_ptr_finder<s64, true>; + +template class memory_share_creator<u8>; +template class memory_share_creator<u16>; +template class memory_share_creator<u32>; +template class memory_share_creator<u64>; + +template class memory_share_creator<s8>; +template class memory_share_creator<s16>; +template class memory_share_creator<s32>; +template class memory_share_creator<s64>; |