mirror of
https://github.com/holub/mame
synced 2025-05-02 20:46:41 +03:00
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.
This commit is contained in:
parent
a610524c5f
commit
c84a6b2530
@ -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)
|
||||
{
|
||||
|
@ -480,7 +480,7 @@ public:
|
||||
offs_t m_globalmask; // global mask
|
||||
simple_list<address_map_entry> m_entrylist; // list of entries
|
||||
|
||||
void import_submaps(running_machine &machine, device_t &owner, int data_width, endianness_t endian);
|
||||
void import_submaps(running_machine &machine, device_t &owner, int data_width, endianness_t endian, int addr_shift);
|
||||
void map_validity_check(validity_checker &valid, int spacenum) const;
|
||||
};
|
||||
|
||||
|
@ -1235,7 +1235,7 @@ void address_space::prepare_map()
|
||||
m_map = std::make_unique<address_map>(m_device, m_spacenum);
|
||||
|
||||
// merge in the submaps
|
||||
m_map->import_submaps(m_manager.machine(), m_device.owner() ? *m_device.owner() : m_device, data_width(), endianness());
|
||||
m_map->import_submaps(m_manager.machine(), m_device.owner() ? *m_device.owner() : m_device, data_width(), endianness(), addr_shift());
|
||||
|
||||
// extract global parameters specified by the map
|
||||
m_unmap = (m_map->m_unmapval == 0) ? 0 : ~0;
|
||||
@ -1859,7 +1859,7 @@ template<int Width, int AddrShift, endianness_t Endian> void address_space_speci
|
||||
{
|
||||
check_address("install_device_delegate", addrstart, addrend);
|
||||
address_map map(*this, addrstart, addrend, unitmask, cswidth, m_device, delegate);
|
||||
map.import_submaps(m_manager.machine(), device, data_width(), endianness());
|
||||
map.import_submaps(m_manager.machine(), device, data_width(), endianness(), addr_shift());
|
||||
populate_from_map(&map);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user