mirror of
https://github.com/holub/mame
synced 2025-05-21 13:18:56 +03:00
memory: Add support for dynamically mapping devices [O. Galibert]
Just call install_device on the space with as parameters: - start and end of the mapping zone - device (not pointer to the device) - map method and optionally, if the device data width is not the same than the space data width: - device data width (for consistency checking) - unit mask For instance, the static mapping: AM_RANGE(0x02114100, 0x02114107) AM_DEVICE8("fdc", n82077aa_device, amap, 0xffffffff) can be converted to a dynamic mapping (where fdc is a pointer to the device): machine().device("maincpu")->memory().space(AS_PROGRAM)-> install_device(0x02114100, 0x02114107, *fdc, &n82077aa_device::amap, 8, 0xffffffff);
This commit is contained in:
parent
bf013678a7
commit
40c79602b6
@ -739,6 +739,38 @@ address_map::address_map(const device_t &device, address_map_entry *entry)
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
// address_map - constructor dynamic device mapping case
|
||||
//----------------------------------------------------------
|
||||
|
||||
address_map::address_map(const address_space &space, offs_t start, offs_t end, int bits, UINT64 unitmask, const device_t &device, address_map_delegate submap_delegate)
|
||||
: m_spacenum(space.spacenum()),
|
||||
m_databits(space.data_width()),
|
||||
m_unmapval(space.unmap()),
|
||||
m_globalmask(space.bytemask())
|
||||
{
|
||||
address_map_entry *e;
|
||||
switch(m_databits) {
|
||||
case 8:
|
||||
e = add(start, end, (address_map_entry8 *)NULL);
|
||||
break;
|
||||
case 16:
|
||||
e = add(start, end, (address_map_entry16 *)NULL);
|
||||
break;
|
||||
case 32:
|
||||
e = add(start, end, (address_map_entry32 *)NULL);
|
||||
break;
|
||||
case 64:
|
||||
e = add(start, end, (address_map_entry64 *)NULL);
|
||||
break;
|
||||
default:
|
||||
throw emu_fatalerror("Trying to dynamically map a device on a space with a corrupt databits width");
|
||||
}
|
||||
e->set_submap(device, DEVICE_SELF, submap_delegate, bits, unitmask);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ~address_map - destructor
|
||||
//-------------------------------------------------
|
||||
|
@ -74,9 +74,6 @@ enum map_handler_type
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// submap retriever delegate
|
||||
typedef delegate<void (address_map &, const device_t &)> address_map_delegate;
|
||||
|
||||
// address map handler data
|
||||
class map_handler_data
|
||||
{
|
||||
@ -411,6 +408,7 @@ public:
|
||||
// construction/destruction
|
||||
address_map(const device_t &device, address_spacenum spacenum);
|
||||
address_map(const device_t &device, address_map_entry *entry);
|
||||
address_map(const address_space &space, offs_t start, offs_t end, int bits, UINT64 unitmask, const device_t &device, address_map_delegate submap_delegate);
|
||||
~address_map();
|
||||
|
||||
// configuration
|
||||
|
@ -1894,19 +1894,23 @@ void address_space::prepare_map()
|
||||
// each case
|
||||
//-------------------------------------------------
|
||||
|
||||
void address_space::populate_from_map()
|
||||
void address_space::populate_from_map(address_map *map)
|
||||
{
|
||||
// no map specified, use the space-specific one
|
||||
if (map == NULL)
|
||||
map = m_map;
|
||||
|
||||
// no map, nothing to do
|
||||
if (m_map == NULL)
|
||||
if (map == NULL)
|
||||
return;
|
||||
|
||||
// install the handlers, using the original, unadjusted memory map
|
||||
const address_map_entry *last_entry = NULL;
|
||||
while (last_entry != m_map->m_entrylist.first())
|
||||
while (last_entry != map->m_entrylist.first())
|
||||
{
|
||||
// find the entry before the last one we processed
|
||||
const address_map_entry *entry;
|
||||
for (entry = m_map->m_entrylist.first(); entry->next() != last_entry; entry = entry->next()) ;
|
||||
for (entry = map->m_entrylist.first(); entry->next() != last_entry; entry = entry->next()) ;
|
||||
last_entry = entry;
|
||||
|
||||
// map both read and write halves
|
||||
@ -2306,6 +2310,20 @@ void address_space::unmap_generic(offs_t addrstart, offs_t addrend, offs_t addrm
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// install_device_delegate - install the memory map
|
||||
// of a live device into this address space
|
||||
//-------------------------------------------------
|
||||
|
||||
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());
|
||||
populate_from_map(&map);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// install_readwrite_port - install a new I/O port
|
||||
// handler into this address space
|
||||
|
@ -107,6 +107,9 @@ typedef UINT32 offs_t;
|
||||
// address map constructors are functions that build up an address_map
|
||||
typedef void (*address_map_constructor)(address_map &map, const device_t &devconfig);
|
||||
|
||||
// submap retriever delegate
|
||||
typedef delegate<void (address_map &, const device_t &)> address_map_delegate;
|
||||
|
||||
|
||||
// legacy space read/write handlers
|
||||
typedef UINT8 (*read8_space_func) (ATTR_UNUSED address_space *space, ATTR_UNUSED offs_t offset);
|
||||
@ -433,6 +436,14 @@ public:
|
||||
void *install_writeonly(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, void *baseptr = NULL) { return install_ram_generic(addrstart, addrend, addrmask, addrmirror, ROW_WRITE, baseptr); }
|
||||
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) {
|
||||
address_map_delegate delegate(map, "dynamic_device_install", &device);
|
||||
install_device_delegate(addrstart, addrend, device, delegate, bits, unitmask);
|
||||
}
|
||||
|
||||
void install_device_delegate(offs_t addrstart, offs_t addrend, device_t &device, address_map_delegate &map, int bits = 0, UINT64 unitmask = 0);
|
||||
|
||||
// install new-style delegate handlers (short form)
|
||||
UINT8 *install_read_handler(offs_t addrstart, offs_t addrend, read8_delegate rhandler, UINT64 unitmask = 0) { return install_read_handler(addrstart, addrend, 0, 0, rhandler, unitmask); }
|
||||
UINT8 *install_write_handler(offs_t addrstart, offs_t addrend, write8_delegate whandler, UINT64 unitmask = 0) { return install_write_handler(addrstart, addrend, 0, 0, whandler, unitmask); }
|
||||
@ -519,7 +530,7 @@ public:
|
||||
|
||||
// setup
|
||||
void prepare_map();
|
||||
void populate_from_map();
|
||||
void populate_from_map(address_map *map = NULL);
|
||||
void allocate_memory();
|
||||
void locate_memory();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user