summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emu/emumem.cpp162
-rw-r--r--src/emu/emumem.h57
2 files changed, 99 insertions, 120 deletions
diff --git a/src/emu/emumem.cpp b/src/emu/emumem.cpp
index 7a4bc4eb2bc..47c89bd8892 100644
--- a/src/emu/emumem.cpp
+++ b/src/emu/emumem.cpp
@@ -1568,30 +1568,30 @@ void memory_manager::initialize()
// 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)
- m_spacelist.append(address_space::allocate(*this, *spaceconfig, memory, spacenum));
+ address_space::allocate(m_spacelist,*this, *spaceconfig, memory, spacenum);
}
// construct and preprocess the address_map for each space
- for (address_space &space : m_spacelist)
- space.prepare_map();
+ for (auto &space : m_spacelist)
+ space->prepare_map();
// create the handlers from the resulting address maps
- for (address_space &space : m_spacelist)
- space.populate_from_map();
+ for (auto &space : m_spacelist)
+ space->populate_from_map();
// allocate memory needed to back each address space
- for (address_space &space : m_spacelist)
- space.allocate_memory();
+ for (auto &space : m_spacelist)
+ space->allocate_memory();
// find all the allocated pointers
- for (address_space &space : m_spacelist)
- space.locate_memory();
+ for (auto &space : m_spacelist)
+ space->locate_memory();
// disable logging of unmapped access when no one receives it
- for (address_space &space : m_spacelist)
+ for (auto &space : m_spacelist)
{
if (!machine().options().log() && !machine().options().oslog() && !(machine().debug_flags & DEBUG_FLAG_ENABLED))
- space.set_log_unmap(false);
+ space->set_log_unmap(false);
}
// register a callback to reset banks when reloading state
@@ -1617,19 +1617,19 @@ void memory_manager::dump(FILE *file)
return;
// loop over address spaces
- for (address_space &space : m_spacelist)
+ 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, ROW_READ);
+ "====================================================\n", space->device().tag(), space->name());
+ space->dump_map(file, ROW_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, ROW_WRITE);
+ "====================================================\n", space->device().tag(), space->name());
+ space->dump_map(file, ROW_WRITE);
}
}
@@ -1721,8 +1721,7 @@ void memory_manager::bank_reattach()
//-------------------------------------------------
address_space::address_space(memory_manager &manager, device_memory_interface &memory, address_spacenum spacenum, bool large)
- : m_next(nullptr),
- m_config(*memory.space_config(spacenum)),
+ : m_config(*memory.space_config(spacenum)),
m_device(memory.device()),
m_addrmask(0xffffffffUL >> (32 - m_config.m_addrbus_width)),
m_bytemask(address_to_byte_end(m_addrmask)),
@@ -1757,7 +1756,7 @@ address_space::~address_space()
// allocate - static smart allocator of subtypes
//-------------------------------------------------
-address_space &address_space::allocate(memory_manager &manager, const address_space_config &config, device_memory_interface &memory, address_spacenum spacenum)
+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, address_spacenum spacenum)
{
// allocate one of the appropriate type
bool large = (config.addr2byte_end(0xffffffffUL >> (32 - config.m_addrbus_width)) >= (1 << 18));
@@ -1767,68 +1766,73 @@ address_space &address_space::allocate(memory_manager &manager, const address_sp
case 8:
if (config.endianness() == ENDIANNESS_LITTLE)
{
- if (large)
- return *global_alloc(address_space_8le_large(manager, memory, spacenum));
+ if (large)
+ space_list.push_back(std::make_unique<address_space_8le_large>(manager, memory, spacenum));
else
- return *global_alloc(address_space_8le_small(manager, memory, spacenum));
+ space_list.push_back(std::make_unique<address_space_8le_small>(manager, memory, spacenum));
}
else
{
- if (large)
- return *global_alloc(address_space_8be_large(manager, memory, spacenum));
+ if (large)
+ space_list.push_back(std::make_unique<address_space_8be_large>(manager, memory, spacenum));
else
- return *global_alloc(address_space_8be_small(manager, memory, spacenum));
+ space_list.push_back(std::make_unique<address_space_8be_small>(manager, memory, spacenum));
}
+ break;
case 16:
if (config.endianness() == ENDIANNESS_LITTLE)
{
- if (large)
- return *global_alloc(address_space_16le_large(manager, memory, spacenum));
+ if (large)
+ space_list.push_back(std::make_unique<address_space_16le_large>(manager, memory, spacenum));
else
- return *global_alloc(address_space_16le_small(manager, memory, spacenum));
+ space_list.push_back(std::make_unique<address_space_16le_small>(manager, memory, spacenum));
}
else
{
if (large)
- return *global_alloc(address_space_16be_large(manager, memory, spacenum));
+ space_list.push_back(std::make_unique<address_space_16be_large>(manager, memory, spacenum));
else
- return *global_alloc(address_space_16be_small(manager, memory, spacenum));
+ space_list.push_back(std::make_unique<address_space_16be_small>(manager, memory, spacenum));
}
+ break;
case 32:
if (config.endianness() == ENDIANNESS_LITTLE)
{
if (large)
- return *global_alloc(address_space_32le_large(manager, memory, spacenum));
+ space_list.push_back(std::make_unique<address_space_32le_large>(manager, memory, spacenum));
else
- return *global_alloc(address_space_32le_small(manager, memory, spacenum));
+ space_list.push_back(std::make_unique<address_space_32le_small>(manager, memory, spacenum));
}
else
{
if (large)
- return *global_alloc(address_space_32be_large(manager, memory, spacenum));
+ space_list.push_back(std::make_unique<address_space_32be_large>(manager, memory, spacenum));
else
- return *global_alloc(address_space_32be_small(manager, memory, spacenum));
+ space_list.push_back(std::make_unique<address_space_32be_small>(manager, memory, spacenum));
}
+ break;
case 64:
if (config.endianness() == ENDIANNESS_LITTLE)
{
if (large)
- return *global_alloc(address_space_64le_large(manager, memory, spacenum));
+ space_list.push_back(std::make_unique<address_space_64le_large>(manager, memory, spacenum));
else
- return *global_alloc(address_space_64le_small(manager, memory, spacenum));
+ space_list.push_back(std::make_unique<address_space_64le_small>(manager, memory, spacenum));
}
else
{
if (large)
- return *global_alloc(address_space_64be_large(manager, memory, spacenum));
+ space_list.push_back(std::make_unique<address_space_64be_large>(manager, memory, spacenum));
else
- return *global_alloc(address_space_64be_small(manager, memory, spacenum));
+ space_list.push_back(std::make_unique<address_space_64be_small>(manager, memory, spacenum));
}
- }
- throw emu_fatalerror("Invalid width %d specified for address_space::allocate", config.data_width());
+ break;
+ default:
+ throw emu_fatalerror("Invalid width %d specified for address_space::allocate", config.data_width());
+ }
}
@@ -2193,20 +2197,20 @@ void address_space::populate_map_entry_setoffset(const address_map_entry &entry)
void address_space::allocate_memory()
{
- simple_list<memory_block> &blocklist = manager().m_blocklist;
+ auto &blocklist = manager().m_blocklist;
// make a first pass over the memory map and track blocks with hardcoded pointers
// we do this to make sure they are found by space_find_backing_memory first
- memory_block *prev_memblock_tail = blocklist.last();
+ int tail = blocklist.size();
for (address_map_entry &entry : m_map->m_entrylist)
if (entry.m_memory != nullptr)
- blocklist.append(*global_alloc(memory_block(*this, entry.m_bytestart, entry.m_byteend, entry.m_memory)));
+ blocklist.push_back(std::make_unique<memory_block>(*this, entry.m_bytestart, entry.m_byteend, entry.m_memory));
// loop over all blocks just allocated and assign pointers from them
address_map_entry *unassigned = nullptr;
- memory_block *first_new_block = (prev_memblock_tail != nullptr) ? prev_memblock_tail->next() : blocklist.first();
- for (memory_block *memblock = first_new_block; memblock != nullptr; memblock = memblock->next())
- unassigned = block_assign_intersecting(memblock->bytestart(), memblock->byteend(), memblock->data());
+
+ for (auto memblock = blocklist.begin() + tail; memblock != blocklist.end(); ++memblock)
+ unassigned = block_assign_intersecting(memblock->get()->bytestart(), memblock->get()->byteend(), memblock->get()->data());
// if we don't have an unassigned pointer yet, try to find one
if (unassigned == nullptr)
@@ -2247,10 +2251,11 @@ void address_space::allocate_memory()
// we now have a block to allocate; do it
offs_t curbytestart = curblockstart * MEMORY_BLOCK_CHUNK;
offs_t curbyteend = curblockend * MEMORY_BLOCK_CHUNK + (MEMORY_BLOCK_CHUNK - 1);
- memory_block &block = blocklist.append(*global_alloc(memory_block(*this, curbytestart, curbyteend)));
-
+ auto block = std::make_unique<memory_block>(*this, curbytestart, curbyteend);
+
// assign memory that intersected the new block
- unassigned = block_assign_intersecting(curbytestart, curbyteend, block.data());
+ unassigned = block_assign_intersecting(curbytestart, curbyteend, block.get()->data());
+ blocklist.push_back(std::move(block));
}
}
@@ -2572,8 +2577,9 @@ void address_space::install_ram_generic(offs_t addrstart, offs_t addrend, offs_t
{
if (machine().phase() >= MACHINE_PHASE_RESET)
fatalerror("Attempted to call install_ram_generic() after initialization time without a baseptr!\n");
- memory_block &block = manager().m_blocklist.append(*global_alloc(memory_block(*this, address_to_byte(addrstart), address_to_byte_end(addrend))));
- bank.set_base(block.data());
+ auto block = std::make_unique<memory_block>(*this, address_to_byte(addrstart), address_to_byte_end(addrend));
+ bank.set_base(block.get()->data());
+ manager().m_blocklist.push_back(std::move(block));
}
}
@@ -2601,8 +2607,9 @@ void address_space::install_ram_generic(offs_t addrstart, offs_t addrend, offs_t
{
if (machine().phase() >= MACHINE_PHASE_RESET)
fatalerror("Attempted to call install_ram_generic() after initialization time without a baseptr!\n");
- memory_block &block = manager().m_blocklist.append(*global_alloc(memory_block(*this, address_to_byte(addrstart), address_to_byte_end(addrend))));
- bank.set_base(block.data());
+ auto block = std::make_unique<memory_block>(*this, address_to_byte(addrstart), address_to_byte_end(addrend));
+ bank.set_base(block.get()->data());
+ manager().m_blocklist.push_back(std::move(block));
}
}
}
@@ -2781,11 +2788,11 @@ void *address_space::find_backing_memory(offs_t addrstart, offs_t addrend)
}
// if not found there, look in the allocated blocks
- for (memory_block &block : manager().m_blocklist)
- if (block.contains(*this, bytestart, byteend))
+ for (auto &block : manager().m_blocklist)
+ if (block->contains(*this, bytestart, byteend))
{
- VPRINTF(("found in allocated memory block %08X-%08X [%p]\n", block.bytestart(), block.byteend(), block.data() + (bytestart - block.bytestart())));
- return block.data() + bytestart - block.bytestart();
+ VPRINTF(("found in allocated memory block %08X-%08X [%p]\n", block->bytestart(), block->byteend(), block->data() + (bytestart - block->bytestart())));
+ return block->data() + bytestart - block->bytestart();
}
VPRINTF(("did not find\n"));
@@ -3953,22 +3960,23 @@ direct_read_data::direct_range *direct_read_data::find_range(offs_t byteaddress,
entry = m_space.read().lookup_live_nowp(byteaddress);
// scan our table
- for (direct_range &range : m_rangelist[entry])
+ for (auto &range : m_rangelist[entry])
if (byteaddress >= range.m_bytestart && byteaddress <= range.m_byteend)
return &range;
// didn't find out; allocate a new one
- direct_range *range = m_freerangelist.first();
- if (range != nullptr)
- m_freerangelist.detach(*range);
- else
- range = global_alloc(direct_range);
+ direct_range range;
+ if (m_freerangelist.size() > 0)
+ {
+ range = m_freerangelist.front();
+ m_freerangelist.pop_front();
+ }
// fill in the range
- m_space.read().derive_range(byteaddress, range->m_bytestart, range->m_byteend);
- m_rangelist[entry].prepend(*range);
+ m_space.read().derive_range(byteaddress, range.m_bytestart, range.m_byteend);
+ m_rangelist[entry].push_front(range);
- return range;
+ return &m_rangelist[entry].front();
}
@@ -3983,16 +3991,13 @@ void direct_read_data::remove_intersecting_ranges(offs_t bytestart, offs_t bytee
for (auto & elem : m_rangelist)
{
// loop over all ranges in this entry's list
- direct_range *nextrange;
- for (direct_range *range = elem.first(); range != nullptr; range = nextrange)
+ for (std::list<direct_range>::iterator range = elem.begin(); range!=elem.end();++range)
{
- nextrange = range->next();
-
// if we intersect, remove and add to the free range list
if (bytestart <= range->m_byteend && byteend >= range->m_bytestart)
{
- elem.detach(*range);
- m_freerangelist.prepend(*range);
+ m_freerangelist.push_front(*range);
+ elem.erase(range);
}
}
}
@@ -4037,8 +4042,7 @@ void direct_read_data::explicit_configure(offs_t bytestart, offs_t byteend, offs
//-------------------------------------------------
memory_block::memory_block(address_space &space, offs_t bytestart, offs_t byteend, void *memory)
- : m_next(nullptr),
- m_machine(space.machine()),
+ : m_machine(space.machine()),
m_space(space),
m_bytestart(bytestart),
m_byteend(byteend),
@@ -4137,8 +4141,8 @@ memory_bank::~memory_bank()
bool memory_bank::references_space(const address_space &space, read_or_write readorwrite) const
{
- for (bank_reference &ref : m_reflist)
- if (ref.matches(space, readorwrite))
+ for (auto &ref : m_reflist)
+ if (ref->matches(space, readorwrite))
return true;
return false;
}
@@ -4154,7 +4158,7 @@ void memory_bank::add_reference(address_space &space, read_or_write readorwrite)
// if we already have a reference, skip it
if (references_space(space, readorwrite))
return;
- m_reflist.append(*global_alloc(bank_reference(space, readorwrite)));
+ m_reflist.push_back(std::make_unique<bank_reference>(space, readorwrite));
}
@@ -4166,8 +4170,8 @@ void memory_bank::add_reference(address_space &space, read_or_write readorwrite)
void memory_bank::invalidate_references()
{
// invalidate all the direct references to any referenced address spaces
- for (bank_reference &ref : m_reflist)
- ref.space().direct().force_update();
+ for (auto &ref : m_reflist)
+ ref->space().direct().force_update();
}
diff --git a/src/emu/emumem.h b/src/emu/emumem.h
index d51829491fc..1bb4a2e278a 100644
--- a/src/emu/emumem.h
+++ b/src/emu/emumem.h
@@ -147,16 +147,14 @@ public:
{
public:
// construction
- direct_range()
- : m_next(nullptr),
- m_bytestart(0),
- m_byteend(~0) { }
-
- // getters
- direct_range *next() const { return m_next; }
+ direct_range(): m_bytestart(0),m_byteend(~0) { }
+
+ inline bool operator==(direct_range val) noexcept
+ { // return true if _Left and _Right identify the same thread
+ return (m_bytestart == val.m_bytestart) && (m_byteend == val.m_byteend);
+ }
// internal state
- direct_range * m_next; // pointer to the next range in the list
offs_t m_bytestart; // starting byte offset of the range
offs_t m_byteend; // ending byte offset of the range
};
@@ -200,8 +198,8 @@ private:
offs_t m_bytestart; // minimum valid byte address
offs_t m_byteend; // maximum valid byte address
UINT16 m_entry; // live entry
- simple_list<direct_range> m_rangelist[TOTAL_MEMORY_BANKS]; // list of ranges for each entry
- simple_list<direct_range> m_freerangelist; // list of recycled range entries
+ std::list<direct_range> m_rangelist[TOTAL_MEMORY_BANKS]; // list of ranges for each entry
+ std::list<direct_range> m_freerangelist; // list of recycled range entries
direct_update_delegate m_directupdate; // fast direct-access update callback
};
@@ -258,20 +256,17 @@ class address_space
friend class address_table_write;
friend class address_table_setoffset;
friend class direct_read_data;
- friend class simple_list<address_space>;
- friend resource_pool_object<address_space>::~resource_pool_object();
protected:
// construction/destruction
address_space(memory_manager &manager, device_memory_interface &memory, address_spacenum spacenum, bool large);
- virtual ~address_space();
public:
+ virtual ~address_space();
// public allocator
- static address_space &allocate(memory_manager &manager, const address_space_config &config, device_memory_interface &memory, address_spacenum spacenum);
+ static void allocate(std::vector<std::unique_ptr<address_space>> &space_list, memory_manager &manager, const address_space_config &config, device_memory_interface &memory, address_spacenum spacenum);
// getters
- address_space *next() const { return m_next; }
memory_manager &manager() const { return m_manager; }
device_t &device() const { return m_device; }
running_machine &machine() const { return m_machine; }
@@ -459,7 +454,6 @@ private:
protected:
// private state
- address_space * m_next; // next address space in the global list
const address_space_config &m_config; // configuration of this space
device_t & m_device; // reference to the owning device
std::unique_ptr<address_map> m_map; // original memory map
@@ -489,9 +483,6 @@ class memory_block
{
DISABLE_COPYING(memory_block);
- friend class simple_list<memory_block>;
- friend resource_pool_object<memory_block>::~resource_pool_object();
-
public:
// construction/destruction
memory_block(address_space &space, offs_t bytestart, offs_t byteend, void *memory = nullptr);
@@ -499,7 +490,6 @@ public:
// getters
running_machine &machine() const { return m_machine; }
- memory_block *next() const { return m_next; }
offs_t bytestart() const { return m_bytestart; }
offs_t byteend() const { return m_byteend; }
UINT8 *data() const { return m_data; }
@@ -512,7 +502,6 @@ public:
private:
// internal state
- memory_block * m_next; // next memory block in the list
running_machine & m_machine; // need the machine to free our memory
address_space & m_space; // which address space are we associated with?
offs_t m_bytestart, m_byteend; // byte-normalized start/end for verifying a match
@@ -526,24 +515,16 @@ private:
// a memory bank is a global pointer to memory that can be shared across devices and changed dynamically
class memory_bank
{
- friend class simple_list<memory_bank>;
- friend resource_pool_object<memory_bank>::~resource_pool_object();
-
// a bank reference is an entry in a list of address spaces that reference a given bank
class bank_reference
{
- friend class simple_list<bank_reference>;
- friend resource_pool_object<bank_reference>::~resource_pool_object();
-
public:
// construction/destruction
bank_reference(address_space &space, read_or_write readorwrite)
- : m_next(nullptr),
- m_space(space),
- m_readorwrite(readorwrite) { }
+ : m_space(space),
+ m_readorwrite(readorwrite) { }
// getters
- bank_reference *next() const { return m_next; }
address_space &space() const { return m_space; }
// does this reference match the space+read/write combination?
@@ -554,7 +535,6 @@ class memory_bank
private:
// internal state
- bank_reference * m_next; // link to the next reference
address_space & m_space; // address space that references us
read_or_write m_readorwrite; // used for read or write?
};
@@ -614,7 +594,7 @@ private:
std::vector<bank_entry> m_entry; // array of entries (dynamically allocated)
std::string m_name; // friendly name for this bank
std::string m_tag; // tag for this bank
- simple_list<bank_reference> m_reflist; // linked list of address spaces referencing this bank
+ std::vector<std::unique_ptr<bank_reference>> m_reflist; // linked list of address spaces referencing this bank
};
@@ -623,8 +603,6 @@ private:
// a memory share contains information about shared memory region
class memory_share
{
- friend class simple_list<memory_share>;
-
public:
// construction/destruction
memory_share(UINT8 width, size_t bytes, endianness_t endianness, void *ptr = nullptr)
@@ -664,9 +642,6 @@ class memory_region
DISABLE_COPYING(memory_region);
friend class memory_manager;
- friend class simple_list<memory_region>;
- friend resource_pool_object<memory_region>::~resource_pool_object();
-
public:
// construction/destruction
memory_region(running_machine &machine, const char *name, UINT32 length, UINT8 width, endianness_t endian);
@@ -707,7 +682,7 @@ private:
class memory_manager
{
friend class address_space;
-
+ friend memory_region::memory_region(running_machine &machine, const char *name, UINT32 length, UINT8 width, endianness_t endian);
public:
// construction/destruction
memory_manager(running_machine &machine);
@@ -740,8 +715,8 @@ private:
UINT8 * m_bank_ptr[TOTAL_MEMORY_BANKS]; // array of bank pointers
- simple_list<address_space> m_spacelist; // list of address spaces
- simple_list<memory_block> m_blocklist; // head of the list of memory blocks
+ 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
UINT16 m_banknext; // next bank to allocate