mirror of
https://github.com/holub/mame
synced 2025-10-07 01:16:22 +03:00
memory: Split the map_range function into a fixed entry mapping one and a dynamically allocating entry one. [O. Galibert]
This commit is contained in:
parent
fb374c78fc
commit
a511ce2d19
113
src/emu/memory.c
113
src/emu/memory.c
@ -786,7 +786,8 @@ public:
|
|||||||
void enable_watchpoints(bool enable = true) { m_live_lookup = enable ? s_watchpoint_table : m_table; }
|
void enable_watchpoints(bool enable = true) { m_live_lookup = enable ? s_watchpoint_table : m_table; }
|
||||||
|
|
||||||
// table mapping helpers
|
// table mapping helpers
|
||||||
UINT8 map_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, UINT8 staticentry = 0);
|
void map_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, UINT8 staticentry);
|
||||||
|
UINT8 setup_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror);
|
||||||
UINT8 derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &byteend) const;
|
UINT8 derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &byteend) const;
|
||||||
|
|
||||||
// misc helpers
|
// misc helpers
|
||||||
@ -857,7 +858,7 @@ public:
|
|||||||
|
|
||||||
// range getter
|
// range getter
|
||||||
handler_entry_proxy<handler_entry_read> handler_map_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, UINT64 mask = 0) {
|
handler_entry_proxy<handler_entry_read> handler_map_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, UINT64 mask = 0) {
|
||||||
UINT32 entry = map_range(bytestart, byteend, bytemask, bytemirror);
|
UINT32 entry = setup_range(bytestart, byteend, bytemask, bytemirror);
|
||||||
return handler_entry_proxy<handler_entry_read>(handler_read(entry), mask);
|
return handler_entry_proxy<handler_entry_read>(handler_read(entry), mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -919,7 +920,7 @@ public:
|
|||||||
|
|
||||||
// range getter
|
// range getter
|
||||||
handler_entry_proxy<handler_entry_write> handler_map_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, UINT64 mask = 0) {
|
handler_entry_proxy<handler_entry_write> handler_map_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, UINT64 mask = 0) {
|
||||||
UINT32 entry = map_range(bytestart, byteend, bytemask, bytemirror);
|
UINT32 entry = setup_range(bytestart, byteend, bytemask, bytemirror);
|
||||||
return handler_entry_proxy<handler_entry_write>(handler_write(entry), mask);
|
return handler_entry_proxy<handler_entry_write>(handler_write(entry), mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3177,12 +3178,11 @@ address_table::~address_table()
|
|||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// map_range - finds an approprite handler entry
|
// map_range - map a specific entry in the address
|
||||||
// and requests to populate the address map with
|
// map
|
||||||
// it
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
UINT8 address_table::map_range(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, UINT8 staticentry)
|
void address_table::map_range(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, UINT8 entry)
|
||||||
{
|
{
|
||||||
// convert addresses to bytes
|
// convert addresses to bytes
|
||||||
offs_t bytestart = addrstart;
|
offs_t bytestart = addrstart;
|
||||||
@ -3196,41 +3196,6 @@ UINT8 address_table::map_range(offs_t addrstart, offs_t addrend, offs_t addrmask
|
|||||||
assert_always((bytestart & (m_space.data_width() / 8 - 1)) == 0, "address_table::map_range called with misaligned start address");
|
assert_always((bytestart & (m_space.data_width() / 8 - 1)) == 0, "address_table::map_range called with misaligned start address");
|
||||||
assert_always((byteend & (m_space.data_width() / 8 - 1)) == (m_space.data_width() / 8 - 1), "address_table::map_range called with misaligned end address");
|
assert_always((byteend & (m_space.data_width() / 8 - 1)) == (m_space.data_width() / 8 - 1), "address_table::map_range called with misaligned end address");
|
||||||
|
|
||||||
// if we weren't given an explicit entry, find a free one
|
|
||||||
UINT8 entry = staticentry;
|
|
||||||
if (entry == STATIC_INVALID)
|
|
||||||
{
|
|
||||||
// two attempts to find an empty
|
|
||||||
for (int attempt = 0; attempt < 2; attempt++)
|
|
||||||
{
|
|
||||||
// scan all possible assigned entries for something unpopulated, or for an exact match
|
|
||||||
for (UINT8 scanentry = STATIC_COUNT; scanentry < SUBTABLE_BASE; scanentry++)
|
|
||||||
{
|
|
||||||
handler_entry &curentry = handler(scanentry);
|
|
||||||
|
|
||||||
// exact match takes precedence
|
|
||||||
if (curentry.matches_exactly(bytestart, byteend, bytemask))
|
|
||||||
{
|
|
||||||
entry = scanentry;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// unpopulated is our second choice
|
|
||||||
if (entry == STATIC_INVALID && !curentry.populated())
|
|
||||||
entry = scanentry;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we didn't find anything, find something to depopulate
|
|
||||||
if (entry != STATIC_INVALID)
|
|
||||||
break;
|
|
||||||
depopulate_unused();
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we utterly failed, it's fatal
|
|
||||||
if (entry == STATIC_INVALID)
|
|
||||||
throw emu_fatalerror("Out of handler entries in address table");
|
|
||||||
}
|
|
||||||
|
|
||||||
// configure the entry to our parameters (but not for static non-banked cases)
|
// configure the entry to our parameters (but not for static non-banked cases)
|
||||||
handler_entry &curentry = handler(entry);
|
handler_entry &curentry = handler(entry);
|
||||||
if (entry <= STATIC_BANKMAX || entry >= STATIC_COUNT)
|
if (entry <= STATIC_BANKMAX || entry >= STATIC_COUNT)
|
||||||
@ -3239,6 +3204,70 @@ UINT8 address_table::map_range(offs_t addrstart, offs_t addrend, offs_t addrmask
|
|||||||
// populate it
|
// populate it
|
||||||
populate_range_mirrored(bytestart, byteend, bytemirror, entry);
|
populate_range_mirrored(bytestart, byteend, bytemirror, entry);
|
||||||
|
|
||||||
|
// recompute any direct access on this space if it is a read modification
|
||||||
|
m_space.m_direct.force_update(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// setup_range - finds an approprite handler entry
|
||||||
|
// and requests to populate the address map with
|
||||||
|
// it
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
UINT8 address_table::setup_range(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror)
|
||||||
|
{
|
||||||
|
// convert addresses to bytes
|
||||||
|
offs_t bytestart = addrstart;
|
||||||
|
offs_t byteend = addrend;
|
||||||
|
offs_t bytemask = addrmask;
|
||||||
|
offs_t bytemirror = addrmirror;
|
||||||
|
m_space.adjust_addresses(bytestart, byteend, bytemask, bytemirror);
|
||||||
|
|
||||||
|
// validity checks
|
||||||
|
assert_always(addrstart <= addrend, "address_table::map_range called with start greater than end");
|
||||||
|
assert_always((bytestart & (m_space.data_width() / 8 - 1)) == 0, "address_table::map_range called with misaligned start address");
|
||||||
|
assert_always((byteend & (m_space.data_width() / 8 - 1)) == (m_space.data_width() / 8 - 1), "address_table::map_range called with misaligned end address");
|
||||||
|
|
||||||
|
// find a free entry
|
||||||
|
UINT8 entry = STATIC_INVALID;
|
||||||
|
// two attempts to find an empty
|
||||||
|
for (int attempt = 0; attempt < 2; attempt++)
|
||||||
|
{
|
||||||
|
// scan all possible assigned entries for something unpopulated, or for an exact match
|
||||||
|
for (UINT8 scanentry = STATIC_COUNT; scanentry < SUBTABLE_BASE; scanentry++)
|
||||||
|
{
|
||||||
|
handler_entry &curentry = handler(scanentry);
|
||||||
|
|
||||||
|
// exact match takes precedence
|
||||||
|
if (curentry.matches_exactly(bytestart, byteend, bytemask))
|
||||||
|
{
|
||||||
|
entry = scanentry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unpopulated is our second choice
|
||||||
|
if (entry == STATIC_INVALID && !curentry.populated())
|
||||||
|
entry = scanentry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we didn't find anything, find something to depopulate
|
||||||
|
if (entry != STATIC_INVALID)
|
||||||
|
break;
|
||||||
|
depopulate_unused();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we utterly failed, it's fatal
|
||||||
|
if (entry == STATIC_INVALID)
|
||||||
|
throw emu_fatalerror("Out of handler entries in address table");
|
||||||
|
|
||||||
|
// configure the entry to our parameters
|
||||||
|
handler_entry &curentry = handler(entry);
|
||||||
|
curentry.configure(bytestart, byteend, bytemask);
|
||||||
|
|
||||||
|
// populate it
|
||||||
|
populate_range_mirrored(bytestart, byteend, bytemirror, entry);
|
||||||
|
|
||||||
// recompute any direct access on this space if it is a read modification
|
// recompute any direct access on this space if it is a read modification
|
||||||
m_space.m_direct.force_update(entry);
|
m_space.m_direct.force_update(entry);
|
||||||
return entry;
|
return entry;
|
||||||
|
Loading…
Reference in New Issue
Block a user