mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00
Make device_memory_interface own its address_spaces
This commit is contained in:
parent
e42bb7d2f1
commit
66de90675f
@ -163,15 +163,30 @@ void device_memory_interface::set_addrmap(int spacenum, address_map_constructor
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_address_space - connect an address space
|
||||
// to a device
|
||||
// dump - dump memory tables to the given file in
|
||||
// human-readable format
|
||||
//-------------------------------------------------
|
||||
|
||||
void device_memory_interface::set_address_space(int spacenum, address_space &space)
|
||||
void device_memory_interface::dump(FILE *file) const
|
||||
{
|
||||
if (spacenum >= int(m_addrspace.size()))
|
||||
m_addrspace.resize(spacenum+1, nullptr);
|
||||
m_addrspace[spacenum] = &space;
|
||||
for (auto const &space : m_addrspace)
|
||||
if (space) {
|
||||
fprintf(file,
|
||||
"\n\n"
|
||||
"====================================================\n"
|
||||
"Device '%s' %s address space read handler dump\n"
|
||||
"====================================================\n",
|
||||
device().tag(), space->name());
|
||||
space->dump_map(file, read_or_write::READ);
|
||||
|
||||
fprintf(file,
|
||||
"\n\n"
|
||||
"====================================================\n"
|
||||
"Device '%s' %s address space write handler dump\n"
|
||||
"====================================================\n",
|
||||
device().tag(), space->name());
|
||||
space->dump_map(file, read_or_write::WRITE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,9 +92,6 @@ public:
|
||||
bool has_configured_map(int index = 0) const { return index >= 0 && index < int(m_address_map.size()) && m_address_map[index]; }
|
||||
address_space &space(int index = 0) const { assert(index >= 0 && index < int(m_addrspace.size()) && m_addrspace[index]); return *m_addrspace[index]; }
|
||||
|
||||
// address space accessors
|
||||
void set_address_space(int spacenum, address_space &space);
|
||||
|
||||
// address translation
|
||||
bool translate(int spacenum, int intention, offs_t &address) { return memory_translate(spacenum, intention, address); }
|
||||
|
||||
@ -102,6 +99,23 @@ public:
|
||||
// just use it
|
||||
device_memory_interface &memory() { return *this; }
|
||||
|
||||
// setup functions - these are called in sequence for all device_memory_interface by the memory manager
|
||||
template <typename Space> void allocate(memory_manager &manager, int spacenum)
|
||||
{
|
||||
assert((0 <= spacenum) && (max_space_count() > spacenum));
|
||||
m_addrspace.resize(std::max<std::size_t>(m_addrspace.size(), spacenum + 1));
|
||||
assert(!m_addrspace[spacenum]);
|
||||
m_addrspace[spacenum] = std::make_unique<Space>(manager, *this, spacenum);
|
||||
}
|
||||
void prepare_maps() { for (auto const &space : m_addrspace) { if (space) { space->prepare_map(); } } }
|
||||
void populate_from_maps() { for (auto const &space : m_addrspace) { if (space) { space->populate_from_map(); } } }
|
||||
void allocate_memory() { for (auto const &space : m_addrspace) { if (space) { space->allocate_memory(); } } }
|
||||
void locate_memory() { for (auto const &space : m_addrspace) { if (space) { space->locate_memory(); } } }
|
||||
void set_log_unmap(bool log) { for (auto const &space : m_addrspace) { if (space) { space->set_log_unmap(log); } } }
|
||||
|
||||
// diagnostic functions
|
||||
void dump(FILE *file) const;
|
||||
|
||||
protected:
|
||||
using space_config_vector = std::vector<std::pair<int, const address_space_config *>>;
|
||||
|
||||
@ -120,8 +134,8 @@ protected:
|
||||
|
||||
private:
|
||||
// internal state
|
||||
std::vector<const address_space_config *> m_address_config; // configuration for each space
|
||||
std::vector<address_space *> m_addrspace; // reported address spaces
|
||||
std::vector<const address_space_config *> m_address_config; // configuration for each space
|
||||
std::vector<std::unique_ptr<address_space>> m_addrspace; // reported address spaces
|
||||
};
|
||||
|
||||
// iterator
|
||||
|
@ -1562,9 +1562,86 @@ void memory_manager::allocate(device_memory_interface &memory)
|
||||
for (int spacenum = 0; spacenum < memory.max_space_count(); ++spacenum)
|
||||
{
|
||||
// if there is a configuration for this space, we need an address space
|
||||
const address_space_config *spaceconfig = memory.space_config(spacenum);
|
||||
if (spaceconfig != nullptr)
|
||||
address_space::allocate(m_spacelist, *this, *spaceconfig, memory, spacenum);
|
||||
address_space_config const *const spaceconfig = memory.space_config(spacenum);
|
||||
if (spaceconfig)
|
||||
{
|
||||
// allocate one of the appropriate type
|
||||
bool const large(spaceconfig->addr2byte_end(0xffffffffUL >> (32 - spaceconfig->m_addrbus_width)) >= (1 << 18));
|
||||
|
||||
switch (spaceconfig->data_width())
|
||||
{
|
||||
case 8:
|
||||
if (spaceconfig->endianness() == ENDIANNESS_LITTLE)
|
||||
{
|
||||
if (large)
|
||||
memory.allocate<address_space_8le_large>(*this, spacenum);
|
||||
else
|
||||
memory.allocate<address_space_8le_small>(*this, spacenum);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (large)
|
||||
memory.allocate<address_space_8be_large>(*this, spacenum);
|
||||
else
|
||||
memory.allocate<address_space_8be_small>(*this, spacenum);
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
if (spaceconfig->endianness() == ENDIANNESS_LITTLE)
|
||||
{
|
||||
if (large)
|
||||
memory.allocate<address_space_16le_large>(*this, spacenum);
|
||||
else
|
||||
memory.allocate<address_space_16le_small>(*this, spacenum);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (large)
|
||||
memory.allocate<address_space_16be_large>(*this, spacenum);
|
||||
else
|
||||
memory.allocate<address_space_16be_small>(*this, spacenum);
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
if (spaceconfig->endianness() == ENDIANNESS_LITTLE)
|
||||
{
|
||||
if (large)
|
||||
memory.allocate<address_space_32le_large>(*this, spacenum);
|
||||
else
|
||||
memory.allocate<address_space_32le_small>(*this, spacenum);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (large)
|
||||
memory.allocate<address_space_32be_large>(*this, spacenum);
|
||||
else
|
||||
memory.allocate<address_space_32be_small>(*this, spacenum);
|
||||
}
|
||||
break;
|
||||
|
||||
case 64:
|
||||
if (spaceconfig->endianness() == ENDIANNESS_LITTLE)
|
||||
{
|
||||
if (large)
|
||||
memory.allocate<address_space_64le_large>(*this, spacenum);
|
||||
else
|
||||
memory.allocate<address_space_64le_small>(*this, spacenum);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (large)
|
||||
memory.allocate<address_space_64be_large>(*this, spacenum);
|
||||
else
|
||||
memory.allocate<address_space_64be_small>(*this, spacenum);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw emu_fatalerror("Invalid width %d specified for memory_manager::allocate", spaceconfig->data_width());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1576,33 +1653,35 @@ void memory_manager::initialize()
|
||||
{
|
||||
// loop over devices and spaces within each device
|
||||
memory_interface_iterator iter(machine().root_device());
|
||||
std::vector<device_memory_interface *> memories;
|
||||
for (device_memory_interface &memory : iter)
|
||||
{
|
||||
memories.push_back(&memory);
|
||||
allocate(memory);
|
||||
}
|
||||
|
||||
allocate(m_machine.m_dummy_space);
|
||||
|
||||
// construct and preprocess the address_map for each space
|
||||
for (auto &space : m_spacelist)
|
||||
space->prepare_map();
|
||||
for (auto const memory : memories)
|
||||
memory->prepare_maps();
|
||||
|
||||
// create the handlers from the resulting address maps
|
||||
for (auto &space : m_spacelist)
|
||||
space->populate_from_map();
|
||||
for (auto const memory : memories)
|
||||
memory->populate_from_maps();
|
||||
|
||||
// allocate memory needed to back each address space
|
||||
for (auto &space : m_spacelist)
|
||||
space->allocate_memory();
|
||||
for (auto const memory : memories)
|
||||
memory->allocate_memory();
|
||||
|
||||
// find all the allocated pointers
|
||||
for (auto &space : m_spacelist)
|
||||
space->locate_memory();
|
||||
for (auto const memory : memories)
|
||||
memory->locate_memory();
|
||||
|
||||
// disable logging of unmapped access when no one receives it
|
||||
for (auto &space : m_spacelist)
|
||||
{
|
||||
if (!machine().options().log() && !machine().options().oslog() && !(machine().debug_flags & DEBUG_FLAG_ENABLED))
|
||||
space->set_log_unmap(false);
|
||||
}
|
||||
if (!machine().options().log() && !machine().options().oslog() && !(machine().debug_flags & DEBUG_FLAG_ENABLED))
|
||||
for (auto const memory : memories)
|
||||
memory->set_log_unmap(false);
|
||||
|
||||
// register a callback to reset banks when reloading state
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(memory_manager::bank_reattach), this));
|
||||
@ -1627,20 +1706,9 @@ void memory_manager::dump(FILE *file)
|
||||
return;
|
||||
|
||||
// loop over address spaces
|
||||
for (auto &space : m_spacelist)
|
||||
{
|
||||
fprintf(file, "\n\n"
|
||||
"====================================================\n"
|
||||
"Device '%s' %s address space read handler dump\n"
|
||||
"====================================================\n", space->device().tag(), space->name());
|
||||
space->dump_map(file, read_or_write::READ);
|
||||
|
||||
fprintf(file, "\n\n"
|
||||
"====================================================\n"
|
||||
"Device '%s' %s address space write handler dump\n"
|
||||
"====================================================\n", space->device().tag(), space->name());
|
||||
space->dump_map(file, read_or_write::WRITE);
|
||||
}
|
||||
memory_interface_iterator iter(machine().root_device());
|
||||
for (device_memory_interface &memory : iter)
|
||||
memory.dump(file);
|
||||
}
|
||||
|
||||
|
||||
@ -1747,8 +1815,6 @@ address_space::address_space(memory_manager &manager, device_memory_interface &m
|
||||
m_manager(manager),
|
||||
m_machine(memory.device().machine())
|
||||
{
|
||||
// notify the device
|
||||
memory.set_address_space(spacenum, *this);
|
||||
}
|
||||
|
||||
|
||||
@ -1761,90 +1827,6 @@ address_space::~address_space()
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// allocate - static smart allocator of subtypes
|
||||
//-------------------------------------------------
|
||||
|
||||
void address_space::allocate(std::vector<std::unique_ptr<address_space>> &space_list,memory_manager &manager, const address_space_config &config, device_memory_interface &memory, int spacenum)
|
||||
{
|
||||
// allocate one of the appropriate type
|
||||
bool large = (config.addr2byte_end(0xffffffffUL >> (32 - config.m_addrbus_width)) >= (1 << 18));
|
||||
|
||||
switch (config.data_width())
|
||||
{
|
||||
case 8:
|
||||
if (config.endianness() == ENDIANNESS_LITTLE)
|
||||
{
|
||||
if (large)
|
||||
space_list.push_back(std::make_unique<address_space_8le_large>(manager, memory, spacenum));
|
||||
else
|
||||
space_list.push_back(std::make_unique<address_space_8le_small>(manager, memory, spacenum));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (large)
|
||||
space_list.push_back(std::make_unique<address_space_8be_large>(manager, memory, spacenum));
|
||||
else
|
||||
space_list.push_back(std::make_unique<address_space_8be_small>(manager, memory, spacenum));
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
if (config.endianness() == ENDIANNESS_LITTLE)
|
||||
{
|
||||
if (large)
|
||||
space_list.push_back(std::make_unique<address_space_16le_large>(manager, memory, spacenum));
|
||||
else
|
||||
space_list.push_back(std::make_unique<address_space_16le_small>(manager, memory, spacenum));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (large)
|
||||
space_list.push_back(std::make_unique<address_space_16be_large>(manager, memory, spacenum));
|
||||
else
|
||||
space_list.push_back(std::make_unique<address_space_16be_small>(manager, memory, spacenum));
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
if (config.endianness() == ENDIANNESS_LITTLE)
|
||||
{
|
||||
if (large)
|
||||
space_list.push_back(std::make_unique<address_space_32le_large>(manager, memory, spacenum));
|
||||
else
|
||||
space_list.push_back(std::make_unique<address_space_32le_small>(manager, memory, spacenum));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (large)
|
||||
space_list.push_back(std::make_unique<address_space_32be_large>(manager, memory, spacenum));
|
||||
else
|
||||
space_list.push_back(std::make_unique<address_space_32be_small>(manager, memory, spacenum));
|
||||
}
|
||||
break;
|
||||
|
||||
case 64:
|
||||
if (config.endianness() == ENDIANNESS_LITTLE)
|
||||
{
|
||||
if (large)
|
||||
space_list.push_back(std::make_unique<address_space_64le_large>(manager, memory, spacenum));
|
||||
else
|
||||
space_list.push_back(std::make_unique<address_space_64le_small>(manager, memory, spacenum));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (large)
|
||||
space_list.push_back(std::make_unique<address_space_64be_large>(manager, memory, spacenum));
|
||||
else
|
||||
space_list.push_back(std::make_unique<address_space_64be_small>(manager, memory, spacenum));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw emu_fatalerror("Invalid width %d specified for address_space::allocate", config.data_width());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// adjust_addresses - adjust addresses for a
|
||||
// given address space in a standard fashion
|
||||
|
@ -226,8 +226,6 @@ protected:
|
||||
|
||||
public:
|
||||
virtual ~address_space();
|
||||
// public allocator
|
||||
static void allocate(std::vector<std::unique_ptr<address_space>> &space_list, memory_manager &manager, const address_space_config &config, device_memory_interface &memory, int spacenum);
|
||||
|
||||
// getters
|
||||
memory_manager &manager() const { return m_manager; }
|
||||
@ -673,7 +671,6 @@ private:
|
||||
|
||||
u8 * m_bank_ptr[TOTAL_MEMORY_BANKS]; // array of bank pointers
|
||||
|
||||
std::vector<std::unique_ptr<address_space>> m_spacelist; // list of address spaces
|
||||
std::vector<std::unique_ptr<memory_block>> m_blocklist; // head of the list of memory blocks
|
||||
|
||||
std::unordered_map<std::string,std::unique_ptr<memory_bank>> m_banklist; // data gathered for each bank
|
||||
|
Loading…
Reference in New Issue
Block a user