diff options
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) { |