diff options
| author | 2019-06-09 19:14:19 -0400 | |
|---|---|---|
| committer | 2019-06-09 19:26:41 -0400 | |
| commit | c84a6b2530bb91c984b3d1ed33bac018baca8407 (patch) | |
| tree | a81b46af7f935473ddda402975f518cb5d3acaed /src/emu/addrmap.cpp | |
| parent | a610524c5f8907897905ce109fc714b2201183de (diff) | |
Make submaps work with address-shifted spaces (nw)
Note that submaps are now assumed to use an address shift of 0. It is possible, though unlikely, for this to cause some breakage.
Diffstat (limited to 'src/emu/addrmap.cpp')
| -rw-r--r-- | src/emu/addrmap.cpp | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/src/emu/addrmap.cpp b/src/emu/addrmap.cpp index 0a2e7a15c98..e1398013670 100644 --- a/src/emu/addrmap.cpp +++ b/src/emu/addrmap.cpp @@ -835,7 +835,7 @@ address_map_entry &address_map::operator()(offs_t start, offs_t end) // import_submaps - propagate in the device submaps //------------------------------------------------- -void address_map::import_submaps(running_machine &machine, device_t &owner, int data_width, endianness_t endian) +void address_map::import_submaps(running_machine &machine, device_t &owner, int data_width, endianness_t endian, int addr_shift) { address_map_entry *prev = nullptr; address_map_entry *entry = m_entrylist.first(); @@ -857,7 +857,7 @@ void address_map::import_submaps(running_machine &machine, device_t &owner, int address_map submap(*mapdevice, entry); // Recursively import if needed - submap.import_submaps(machine, *mapdevice, data_width, endian); + submap.import_submaps(machine, *mapdevice, data_width, endian, addr_shift); offs_t max_end = entry->m_addrend - entry->m_addrstart; @@ -867,6 +867,24 @@ void address_map::import_submaps(running_machine &machine, device_t &owner, int while (submap.m_entrylist.count()) { address_map_entry *subentry = submap.m_entrylist.detach_head(); + + if (addr_shift > 0) + { + subentry->m_addrstart <<= addr_shift; + subentry->m_addrend = ((subentry->m_addrend + 1) << addr_shift) - 1; + subentry->m_addrmirror <<= addr_shift; + subentry->m_addrmask <<= addr_shift; + subentry->m_addrselect <<= addr_shift; + } + else if (addr_shift < 0) + { + subentry->m_addrstart >>= -addr_shift; + subentry->m_addrend >>= -addr_shift; + subentry->m_addrmirror >>= -addr_shift; + subentry->m_addrmask >>= -addr_shift; + subentry->m_addrselect >>= -addr_shift; + } + if (subentry->m_addrend > max_end) subentry->m_addrend = max_end; @@ -895,6 +913,10 @@ void address_map::import_submaps(running_machine &machine, device_t &owner, int if ((entry->m_mask >> i) & 1) ratio ++; ratio = data_width / ratio; + if (addr_shift > 0) + ratio <<= addr_shift; + else if (addr_shift < 0) + max_end = ((max_end + 1) << -addr_shift) - 1; max_end = (max_end + 1) / ratio - 1; // Then merge the contents taking the ratio into account @@ -933,11 +955,22 @@ void address_map::import_submaps(running_machine &machine, device_t &owner, int if (subentry->m_addrend > max_end) subentry->m_addrend = max_end; - subentry->m_addrstart = subentry->m_addrstart * ratio + entry->m_addrstart; - subentry->m_addrend = (subentry->m_addrend + 1) * ratio - 1 + entry->m_addrstart; - subentry->m_addrmirror = (subentry->m_addrmirror / ratio) | entry->m_addrmirror; - subentry->m_addrmask = (subentry->m_addrmask / ratio) | entry->m_addrmask; - subentry->m_addrselect = (subentry->m_addrselect / ratio) | entry->m_addrselect; + if (addr_shift < 0) + { + subentry->m_addrstart = ((subentry->m_addrstart * ratio) >> -addr_shift) + entry->m_addrstart; + subentry->m_addrend = (((subentry->m_addrend + 1) * ratio - 1) >> -addr_shift) + entry->m_addrstart; + subentry->m_addrmirror = ((subentry->m_addrmirror / ratio) << -addr_shift) | entry->m_addrmirror; + subentry->m_addrmask = ((subentry->m_addrmask / ratio) << -addr_shift) | entry->m_addrmask; + subentry->m_addrselect = ((subentry->m_addrselect / ratio) << -addr_shift) | entry->m_addrselect; + } + else + { + subentry->m_addrstart = subentry->m_addrstart * ratio + entry->m_addrstart; + subentry->m_addrend = (subentry->m_addrend + 1) * ratio - 1 + entry->m_addrstart; + subentry->m_addrmirror = (subentry->m_addrmirror / ratio) | entry->m_addrmirror; + subentry->m_addrmask = (subentry->m_addrmask / ratio) | entry->m_addrmask; + subentry->m_addrselect = (subentry->m_addrselect / ratio) | entry->m_addrselect; + } if (subentry->m_addrstart > entry->m_addrend) { |
