diff --git a/src/emu/emumem.cpp b/src/emu/emumem.cpp index ca24883e2f393..11f39dcb89a55 100644 --- a/src/emu/emumem.cpp +++ b/src/emu/emumem.cpp @@ -53,6 +53,19 @@ void handler_entry::dump_map(std::vector &map) const fatalerror("dump_map called on non-dispatching class\n"); } +bool handler_entry::is_handler_in_map(std::vector &map, offs_t begin, offs_t end, handler_entry *handler) const +{ + auto it = std::find_if(map.begin(), map.end(), [handler,begin,end](const memory_entry& e) { + return (e.entry == handler) && (e.start == begin) && (e.end == end); + } ); + + if(it == map.end()) { + return false; + } + + return true; +} + void handler_entry::select_a(int slot) { fatalerror("select_a called on non-view\n"); diff --git a/src/emu/emumem.h b/src/emu/emumem.h index 39470a45632d6..c18f58a55e522 100644 --- a/src/emu/emumem.h +++ b/src/emu/emumem.h @@ -608,6 +608,7 @@ class handler_entry inline u32 f_get_pt() const { return (m_flags >> F_PT_BITS) & 15; } virtual void dump_map(std::vector &map) const; + bool is_handler_in_map(std::vector &map, offs_t begin, offs_t end, handler_entry *handler) const; virtual std::string name() const = 0; virtual void enumerate_references(handler_entry::reflist &refs) const; diff --git a/src/emu/emumem_hedr.ipp b/src/emu/emumem_hedr.ipp index 5ac845b0fef58..9444c0c07821e 100644 --- a/src/emu/emumem_hedr.ipp +++ b/src/emu/emumem_hedr.ipp @@ -107,41 +107,64 @@ template offs_t handler_entry_read_dispa template void handler_entry_read_dispatch::dump_map(std::vector &map) const { if(m_view) { - offs_t base_cur = map.empty() ? m_view->m_addrstart & HIGHMASK : map.back().end + 1; for(u32 i = 0; i != m_dispatch_array.size(); i++) { - u32 j = map.size(); - offs_t cur = base_cur; - offs_t end = m_global_range.end + 1; - + u32 map_start_index = map.size(); + offs_t j = 0; + offs_t k = j + 1; + handler_entry *handle = m_dispatch_array[i][j]; do { - offs_t entry = (cur >> LowBits) & BITMASK; - if(m_dispatch_array[i][entry]->is_dispatch() || m_dispatch_array[i][entry]->is_view()) - m_dispatch_array[i][entry]->dump_map(map); - else - map.emplace_back(memory_entry{ m_ranges_array[i][entry].start, m_ranges_array[i][entry].end, m_dispatch_array[i][entry] }); - cur = map.back().end + 1; - } while(cur != end); + while((handle == m_dispatch_array[i][k]) && (k < BITMASK)) { + k++; + } + + k--; + + if(m_dispatch_array[i][j]->is_dispatch() || m_dispatch_array[i][j]->is_view()) { + m_dispatch_array[i][j]->dump_map(map); + } else { + if(!handler_entry::is_handler_in_map(map, m_ranges_array[i][j].start, m_ranges_array[i][j].end, m_dispatch_array[i][j])) { + map.emplace_back(memory_entry{ m_ranges_array[i][j].start, m_ranges_array[i][k].end, m_dispatch_array[i][j]}); + } + } + + j = k + 1; + k = j + 1; + handle = m_dispatch_array[i][j]; + } while (j < BITMASK); + if(i == 0) { - for(u32 k = j; k != map.size(); k++) + for(u32 k = map_start_index; k != map.size(); k++) map[k].context.emplace(map[k].context.begin(), memory_entry_context{ m_view, true, 0 }); } else { int slot = m_view->id_to_slot(int(i)-1); - for(u32 k = j; k != map.size(); k++) + for(u32 k = map_start_index; k != map.size(); k++) map[k].context.emplace(map[k].context.begin(), memory_entry_context{ m_view, false, slot }); } } } else { - offs_t cur = map.empty() ? 0 : map.back().end + 1; - offs_t base = cur & UPMASK; - offs_t end = m_global_range.end + 1; + offs_t j = 0; + offs_t k = j + 1; + handler_entry *the_handler; do { - offs_t entry = (cur >> LowBits) & BITMASK; - if(m_a_dispatch[entry]->is_dispatch() || m_a_dispatch[entry]->is_view()) - m_a_dispatch[entry]->dump_map(map); - else - map.emplace_back(memory_entry{ m_a_ranges[entry].start, m_a_ranges[entry].end, m_a_dispatch[entry] }); - cur = map.back().end + 1; - } while(cur != end && !((cur ^ base) & UPMASK)); + the_handler = m_a_dispatch[j]; + while((the_handler == m_a_dispatch[k]) && (k < COUNT)) { + k++; + } + + k--; + + for(unsigned int z = j; z <= k; z++) { + if(!handler_entry::is_handler_in_map(map, m_a_ranges[z].start, m_a_ranges[z].end, m_a_dispatch[z])) { + if(m_a_dispatch[z]->is_dispatch() || m_a_dispatch[z]->is_view()) { + m_a_dispatch[z]->dump_map(map); + } + else + map.emplace_back(memory_entry{m_a_ranges[z].start,m_a_ranges[z].end,m_a_dispatch[z]}); + } + } + j = k + 1; + k = j + 1; + } while(j < COUNT); } } diff --git a/src/emu/emumem_hedw.ipp b/src/emu/emumem_hedw.ipp index a3d8f78bb07c6..c85a0dc0a86d0 100644 --- a/src/emu/emumem_hedw.ipp +++ b/src/emu/emumem_hedw.ipp @@ -108,40 +108,64 @@ template offs_t handler_entry_write_disp template void handler_entry_write_dispatch::dump_map(std::vector &map) const { if(m_view) { - offs_t base_cur = map.empty() ? m_view->m_addrstart & HIGHMASK : map.back().end + 1; for(u32 i = 0; i != m_dispatch_array.size(); i++) { - u32 j = map.size(); - offs_t cur = base_cur; - offs_t end = m_global_range.end + 1; + u32 map_start_index = map.size(); + offs_t j = 0; + offs_t k = j + 1; + handler_entry *handle = m_dispatch_array[i][j]; do { - offs_t entry = (cur >> LowBits) & BITMASK; - if(m_dispatch_array[i][entry]->is_dispatch() || m_dispatch_array[i][entry]->is_view()) - m_dispatch_array[i][entry]->dump_map(map); - else - map.emplace_back(memory_entry{ m_ranges_array[i][entry].start, m_ranges_array[i][entry].end, m_dispatch_array[i][entry] }); - cur = map.back().end + 1; - } while(cur != end); + while((handle == m_dispatch_array[i][k]) && (k < BITMASK)) { + k++; + } + + k--; + + if(m_dispatch_array[i][j]->is_dispatch() || m_dispatch_array[i][j]->is_view()) { + m_dispatch_array[i][j]->dump_map(map); + } else { + if(!handler_entry::is_handler_in_map(map, m_ranges_array[i][j].start, m_ranges_array[i][j].end, m_dispatch_array[i][j])) { + map.emplace_back(memory_entry{ m_ranges_array[i][j].start, m_ranges_array[i][k].end, m_dispatch_array[i][j]}); + } + } + + j = k + 1; + k = j + 1; + handle = m_dispatch_array[i][j]; + } while (j < BITMASK); + if(i == 0) { - for(u32 k = j; k != map.size(); k++) + for(u32 k = map_start_index; k != map.size(); k++) map[k].context.emplace(map[k].context.begin(), memory_entry_context{ m_view, true, 0 }); } else { int slot = m_view->id_to_slot(int(i)-1); - for(u32 k = j; k != map.size(); k++) + for(u32 k = map_start_index; k != map.size(); k++) map[k].context.emplace(map[k].context.begin(), memory_entry_context{ m_view, false, slot }); } } } else { - offs_t cur = map.empty() ? 0 : map.back().end + 1; - offs_t base = cur & UPMASK; - offs_t end = m_global_range.end + 1; + offs_t j = 0; + offs_t k = j + 1; + handler_entry *the_handler; do { - offs_t entry = (cur >> LowBits) & BITMASK; - if(m_a_dispatch[entry]->is_dispatch() || m_a_dispatch[entry]->is_view()) - m_a_dispatch[entry]->dump_map(map); - else - map.emplace_back(memory_entry{ m_a_ranges[entry].start, m_a_ranges[entry].end, m_a_dispatch[entry] }); - cur = map.back().end + 1; - } while(cur != end && !((cur ^ base) & UPMASK)); + the_handler = m_a_dispatch[j]; + while((the_handler == m_a_dispatch[k]) && (k < COUNT)) { + k++; + } + + k--; + + for(unsigned int z = j; z <= k; z++) { + if(!handler_entry::is_handler_in_map(map, m_a_ranges[z].start, m_a_ranges[z].end, m_a_dispatch[z])) { + if(m_a_dispatch[z]->is_dispatch() || m_a_dispatch[z]->is_view()) { + m_a_dispatch[z]->dump_map(map); + } + else + map.emplace_back(memory_entry{m_a_ranges[z].start,m_a_ranges[z].end,m_a_dispatch[z]}); + } + } + j = k + 1; + k = j + 1; + } while(j < COUNT); } }