memory: Fix dynamic recursive device mapping [O. Galibert]

Situation:
- you have a device (pc-fdc) with a memory map on it
- you map it dynamically into a cpu (maincpu) address space with install_device (isa-fdc does that)
- the device pc-fdc has a subdevice (upd765)
- the subdevice upd765 has its own memory map
- the pc-fdc memory map includes the upd765 memory map through AM_DEVICE("upd765", ...)

Before the fix, the code would search for upd765 as a subdevice of
maincpu and not of pc-fdc.
This commit is contained in:
Olivier Galibert 2012-10-10 15:33:36 +00:00
parent 6323d3af12
commit 5a2289ab25
4 changed files with 11 additions and 9 deletions

View File

@ -716,7 +716,7 @@ address_map_entry64 *address_map::add(offs_t start, offs_t end, address_map_entr
// uplift_submaps - propagate in the device submaps
//-------------------------------------------------
void address_map::uplift_submaps(running_machine &machine, device_t &device, endianness_t endian)
void address_map::uplift_submaps(running_machine &machine, device_t &device, device_t &owner, endianness_t endian)
{
address_map_entry *prev = 0;
address_map_entry *entry = m_entrylist.first();
@ -724,15 +724,17 @@ void address_map::uplift_submaps(running_machine &machine, device_t &device, end
{
if (entry->m_read.m_type == AMH_DEVICE_SUBMAP)
{
const char *tag = entry->m_read.m_tag;
astring tag;
owner.subtag(tag, entry->m_read.m_tag);
device_t *mapdevice = machine.device(tag);
if (mapdevice == NULL)
throw emu_fatalerror("Attempted to submap a non-existent device '%s' in space %d of device '%s'\n", tag, m_spacenum, device.tag());
if (mapdevice == NULL) {
throw emu_fatalerror("Attempted to submap a non-existent device '%s' in space %d of device '%s'\n", tag.cstr(), m_spacenum, device.basetag());
}
// Grab the submap
address_map submap(*mapdevice, entry);
// Recursively uplift it if needed
submap.uplift_submaps(machine, *mapdevice, endian);
submap.uplift_submaps(machine, device, *mapdevice, endian);
// Compute the unit repartition characteristics
int entry_bits = entry->m_submap_bits;

View File

@ -365,7 +365,7 @@ public:
offs_t m_globalmask; // global mask
simple_list<address_map_entry> m_entrylist; // list of entries
void uplift_submaps(running_machine &machine, device_t &device, endianness_t endian);
void uplift_submaps(running_machine &machine, device_t &device, device_t &owner, endianness_t endian);
};

View File

@ -1783,7 +1783,7 @@ void address_space::prepare_map()
m_map = global_alloc(address_map(m_device, m_spacenum));
// merge in the submaps
m_map->uplift_submaps(machine(), m_device, endianness());
m_map->uplift_submaps(machine(), m_device, machine().root_device(), endianness());
// extract global parameters specified by the map
m_unmap = (m_map->m_unmapval == 0) ? 0 : ~0;
@ -2251,7 +2251,7 @@ void address_space::unmap_generic(offs_t addrstart, offs_t addrend, offs_t addrm
void address_space::install_device_delegate(offs_t addrstart, offs_t addrend, device_t &device, address_map_delegate &delegate, int bits, UINT64 unitmask)
{
address_map map(*this, addrstart, addrend, bits, unitmask, device, delegate);
map.uplift_submaps(machine(), m_device, endianness());
map.uplift_submaps(machine(), m_device, device, endianness());
populate_from_map(&map);
}

View File

@ -437,7 +437,7 @@ public:
void *install_ram(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, void *baseptr = NULL) { return install_ram_generic(addrstart, addrend, addrmask, addrmirror, ROW_READWRITE, baseptr); }
// install device memory maps
template <typename T> void install_device(offs_t addrstart, offs_t addrend, T &device, void (T::*map)(address_map &map, const device_t &device), int bits = 0, UINT64 unitmask = 0) {
template <typename T> void install_device(offs_t addrstart, offs_t addrend, T &device, void (T::*map)(address_map &map, device_t &device), int bits = 0, UINT64 unitmask = 0) {
address_map_delegate delegate(map, "dynamic_device_install", &device);
install_device_delegate(addrstart, addrend, device, delegate, bits, unitmask);
}