Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/emu/emumem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ void handler_entry::dump_map(std::vector<memory_entry> &map) const
fatalerror("dump_map called on non-dispatching class\n");
}

bool handler_entry::is_handler_in_map(std::vector<memory_entry> &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");
Expand Down
1 change: 1 addition & 0 deletions src/emu/emumem.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<memory_entry> &map) const;
bool is_handler_in_map(std::vector<memory_entry> &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;
Expand Down
71 changes: 47 additions & 24 deletions src/emu/emumem_hedr.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -107,41 +107,64 @@ template<int HighBits, int Width, int AddrShift> offs_t handler_entry_read_dispa
template<int HighBits, int Width, int AddrShift> void handler_entry_read_dispatch<HighBits, Width, AddrShift>::dump_map(std::vector<memory_entry> &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++;
}
Comment on lines +116 to +118
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this even safe? It looks like it has the potential to read off the end of a single-element array. The same thing happens further down. These sorts of “decrement counter after the loop” things are fertile ground for bugs.

@galibert have you looked at this PR?


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

Expand Down
70 changes: 47 additions & 23 deletions src/emu/emumem_hedw.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -108,40 +108,64 @@ template<int HighBits, int Width, int AddrShift> offs_t handler_entry_write_disp
template<int HighBits, int Width, int AddrShift> void handler_entry_write_dispatch<HighBits, Width, AddrShift>::dump_map(std::vector<memory_entry> &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);
}
}

Expand Down
Loading