summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/addrmap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/addrmap.cpp')
-rw-r--r--src/emu/addrmap.cpp47
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)
{