summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/emumem.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/emumem.h')
-rw-r--r--src/emu/emumem.h149
1 files changed, 81 insertions, 68 deletions
diff --git a/src/emu/emumem.h b/src/emu/emumem.h
index 1b9b6363622..39470a45632 100644
--- a/src/emu/emumem.h
+++ b/src/emu/emumem.h
@@ -71,26 +71,6 @@ using offs_t = u32;
// address map constructors are delegates that build up an address_map
using address_map_constructor = named_delegate<void (address_map &)>;
-// struct with function pointers for accessors; use is generally discouraged unless necessary
-struct data_accessors
-{
- u8 (*read_byte)(address_space &space, offs_t address);
- u16 (*read_word)(address_space &space, offs_t address);
- u16 (*read_word_masked)(address_space &space, offs_t address, u16 mask);
- u32 (*read_dword)(address_space &space, offs_t address);
- u32 (*read_dword_masked)(address_space &space, offs_t address, u32 mask);
- u64 (*read_qword)(address_space &space, offs_t address);
- u64 (*read_qword_masked)(address_space &space, offs_t address, u64 mask);
-
- void (*write_byte)(address_space &space, offs_t address, u8 data);
- void (*write_word)(address_space &space, offs_t address, u16 data);
- void (*write_word_masked)(address_space &space, offs_t address, u16 data, u16 mask);
- void (*write_dword)(address_space &space, offs_t address, u32 data);
- void (*write_dword_masked)(address_space &space, offs_t address, u32 data, u32 mask);
- void (*write_qword)(address_space &space, offs_t address, u64 data);
- void (*write_qword_masked)(address_space &space, offs_t address, u64 data, u64 mask);
-};
-
// a line in the memory structure dump
struct memory_entry_context {
memory_view *view;
@@ -1641,85 +1621,85 @@ template<int Width, int AddrShift, endianness_t Endian, int TargetWidth, bool Al
template<int Level, int Width, int AddrShift> emu::detail::handler_entry_size_t<Width> dispatch_read(offs_t mask, offs_t offset, emu::detail::handler_entry_size_t<Width> mem_mask, const handler_entry_read<Width, AddrShift> *const *dispatch)
{
- static constexpr u32 LowBits = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
- return dispatch[(offset & mask) >> LowBits]->read(offset, mem_mask);
+ constexpr u32 LOW_BITS = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
+ return dispatch[(offset & mask) >> LOW_BITS]->read(offset, mem_mask);
}
template<int Level, int Width, int AddrShift> void dispatch_write(offs_t mask, offs_t offset, emu::detail::handler_entry_size_t<Width> data, emu::detail::handler_entry_size_t<Width> mem_mask, const handler_entry_write<Width, AddrShift> *const *dispatch)
{
- static constexpr u32 LowBits = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
- return dispatch[(offset & mask) >> LowBits]->write(offset, data, mem_mask);
+ constexpr u32 LOW_BITS = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
+ return dispatch[(offset & mask) >> LOW_BITS]->write(offset, data, mem_mask);
}
template<int Level, int Width, int AddrShift> std::pair<emu::detail::handler_entry_size_t<Width>, u16> dispatch_read_flags(offs_t mask, offs_t offset, emu::detail::handler_entry_size_t<Width> mem_mask, const handler_entry_read<Width, AddrShift> *const *dispatch)
{
- static constexpr u32 LowBits = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
- return dispatch[(offset & mask) >> LowBits]->read_flags(offset, mem_mask);
+ constexpr u32 LOW_BITS = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
+ return dispatch[(offset & mask) >> LOW_BITS]->read_flags(offset, mem_mask);
}
template<int Level, int Width, int AddrShift> u16 dispatch_write_flags(offs_t mask, offs_t offset, emu::detail::handler_entry_size_t<Width> data, emu::detail::handler_entry_size_t<Width> mem_mask, const handler_entry_write<Width, AddrShift> *const *dispatch)
{
- static constexpr u32 LowBits = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
- return dispatch[(offset & mask) >> LowBits]->write_flags(offset, data, mem_mask);
+ constexpr u32 LOW_BITS = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
+ return dispatch[(offset & mask) >> LOW_BITS]->write_flags(offset, data, mem_mask);
}
template<int Level, int Width, int AddrShift> u16 dispatch_lookup_read_flags(offs_t mask, offs_t offset, emu::detail::handler_entry_size_t<Width> mem_mask, const handler_entry_read<Width, AddrShift> *const *dispatch)
{
- static constexpr u32 LowBits = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
- return dispatch[(offset & mask) >> LowBits]->lookup_flags(offset, mem_mask);
+ constexpr u32 LOW_BITS = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
+ return dispatch[(offset & mask) >> LOW_BITS]->lookup_flags(offset, mem_mask);
}
template<int Level, int Width, int AddrShift> u16 dispatch_lookup_write_flags(offs_t mask, offs_t offset, emu::detail::handler_entry_size_t<Width> mem_mask, const handler_entry_write<Width, AddrShift> *const *dispatch)
{
- static constexpr u32 LowBits = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
- return dispatch[(offset & mask) >> LowBits]->lookup_flags(offset, mem_mask);
+ constexpr u32 LOW_BITS = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
+ return dispatch[(offset & mask) >> LOW_BITS]->lookup_flags(offset, mem_mask);
}
template<int Level, int Width, int AddrShift> emu::detail::handler_entry_size_t<Width> dispatch_read_interruptible(offs_t mask, offs_t offset, emu::detail::handler_entry_size_t<Width> mem_mask, const handler_entry_read<Width, AddrShift> *const *dispatch)
{
- static constexpr u32 LowBits = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
- return dispatch[(offset & mask) >> LowBits]->read_interruptible(offset, mem_mask);
+ constexpr u32 LOW_BITS = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
+ return dispatch[(offset & mask) >> LOW_BITS]->read_interruptible(offset, mem_mask);
}
template<int Level, int Width, int AddrShift> void dispatch_write_interruptible(offs_t mask, offs_t offset, emu::detail::handler_entry_size_t<Width> data, emu::detail::handler_entry_size_t<Width> mem_mask, const handler_entry_write<Width, AddrShift> *const *dispatch)
{
- static constexpr u32 LowBits = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
- return dispatch[(offset & mask) >> LowBits]->write_interruptible(offset, data, mem_mask);
+ constexpr u32 LOW_BITS = emu::detail::handler_entry_dispatch_level_to_lowbits(Level, Width, AddrShift);
+ return dispatch[(offset & mask) >> LOW_BITS]->write_interruptible(offset, data, mem_mask);
}
+namespace emu::detail {
+
// ======================> memory_access_specific
// memory_access_specific does uncached but faster accesses by shortcutting the address_space virtual call
-namespace emu::detail {
-
template<int Level, int Width, int AddrShift, endianness_t Endian> class memory_access_specific
{
friend class ::address_space;
using NativeType = emu::detail::handler_entry_size_t<Width>;
static constexpr u32 NATIVE_BYTES = 1 << Width;
- static constexpr u32 NATIVE_MASK = Width + AddrShift >= 0 ? (1 << (Width + AddrShift)) - 1 : 0;
+ static constexpr u32 NATIVE_MASK = (Width + AddrShift >= 0) ? ((1 << (Width + AddrShift)) - 1) : 0;
public:
// construction/destruction
- memory_access_specific()
- : m_space(nullptr),
- m_addrmask(0),
- m_dispatch_read(nullptr),
- m_dispatch_write(nullptr)
+ memory_access_specific() :
+ m_space(nullptr),
+ m_addrmask(0),
+ m_dispatch_read(nullptr),
+ m_dispatch_write(nullptr)
{
}
- inline address_space &space() const {
+ address_space &space() const {
return *m_space;
}
@@ -1731,6 +1711,7 @@ public:
auto lwopf() { return [this](offs_t offset, NativeType mask) -> u16 { return lookup_write_native_flags(offset, mask); }; }
u8 read_byte(offs_t address) { if constexpr(Width == 0) return read_native(address & ~NATIVE_MASK); else return memory_read_generic<Width, AddrShift, Endian, 0, true>(rop(), address, 0xff); }
+ u8 read_byte(offs_t address, u8 mask) { return memory_read_generic<Width, AddrShift, Endian, 0, true>(rop(), address, mask); }
u16 read_word(offs_t address) { if constexpr(Width == 1) return read_native(address & ~NATIVE_MASK); else return memory_read_generic<Width, AddrShift, Endian, 1, true>(rop(), address, 0xffff); }
u16 read_word(offs_t address, u16 mask) { return memory_read_generic<Width, AddrShift, Endian, 1, true>(rop(), address, mask); }
u16 read_word_unaligned(offs_t address) { return memory_read_generic<Width, AddrShift, Endian, 1, false>(rop(), address, 0xffff); }
@@ -1745,6 +1726,7 @@ public:
u64 read_qword_unaligned(offs_t address, u64 mask) { return memory_read_generic<Width, AddrShift, Endian, 3, false>(rop(), address, mask); }
void write_byte(offs_t address, u8 data) { if constexpr(Width == 0) write_native(address & ~NATIVE_MASK, data); else memory_write_generic<Width, AddrShift, Endian, 0, true>(wop(), address, data, 0xff); }
+ void write_byte(offs_t address, u8 data, u8 mask) { memory_write_generic<Width, AddrShift, Endian, 0, true>(wop(), address, data, mask); }
void write_word(offs_t address, u16 data) { if constexpr(Width == 1) write_native(address & ~NATIVE_MASK, data); else memory_write_generic<Width, AddrShift, Endian, 1, true>(wop(), address, data, 0xffff); }
void write_word(offs_t address, u16 data, u16 mask) { memory_write_generic<Width, AddrShift, Endian, 1, true>(wop(), address, data, mask); }
void write_word_unaligned(offs_t address, u16 data) { memory_write_generic<Width, AddrShift, Endian, 1, false>(wop(), address, data, 0xffff); }
@@ -1760,6 +1742,7 @@ public:
std::pair<u8, u16> read_byte_flags(offs_t address) { if constexpr(Width == 0) return read_native_flags(address & ~NATIVE_MASK); else return memory_read_generic_flags<Width, AddrShift, Endian, 0, true>(ropf(), address, 0xff); }
+ std::pair<u8, u16> read_byte_flags(offs_t address, u8 mask) { return memory_read_generic_flags<Width, AddrShift, Endian, 0, true>(ropf(), address, mask); }
std::pair<u16, u16> read_word_flags(offs_t address) { if constexpr(Width == 1) return read_native_flags(address & ~NATIVE_MASK); else return memory_read_generic_flags<Width, AddrShift, Endian, 1, true>(ropf(), address, 0xffff); }
std::pair<u16, u16> read_word_flags(offs_t address, u16 mask) { return memory_read_generic_flags<Width, AddrShift, Endian, 1, true>(ropf(), address, mask); }
std::pair<u16, u16> read_word_unaligned_flags(offs_t address) { return memory_read_generic_flags<Width, AddrShift, Endian, 1, false>(ropf(), address, 0xffff); }
@@ -1774,6 +1757,7 @@ public:
std::pair<u64, u16> read_qword_unaligned_flags(offs_t address, u64 mask) { return memory_read_generic_flags<Width, AddrShift, Endian, 3, false>(ropf(), address, mask); }
u16 write_byte_flags(offs_t address, u8 data) { if constexpr(Width == 0) return write_native_flags(address & ~NATIVE_MASK, data); else return memory_write_generic_flags<Width, AddrShift, Endian, 0, true>(wopf(), address, data, 0xff); }
+ u16 write_byte_flags(offs_t address, u8 data, u8 mask) { return memory_write_generic_flags<Width, AddrShift, Endian, 0, true>(wopf(), address, data, mask); }
u16 write_word_flags(offs_t address, u16 data) { if constexpr(Width == 1) return write_native_flags(address & ~NATIVE_MASK, data); else return memory_write_generic_flags<Width, AddrShift, Endian, 1, true>(wopf(), address, data, 0xffff); }
u16 write_word_flags(offs_t address, u16 data, u16 mask) { return memory_write_generic_flags<Width, AddrShift, Endian, 1, true>(wopf(), address, data, mask); }
u16 write_word_unaligned_flags(offs_t address, u16 data) { return memory_write_generic_flags<Width, AddrShift, Endian, 1, false>(wopf(), address, data, 0xffff); }
@@ -1788,6 +1772,7 @@ public:
u16 write_qword_unaligned_flags(offs_t address, u64 data, u64 mask) { return memory_write_generic_flags<Width, AddrShift, Endian, 3, false>(wopf(), address, data, mask); }
u16 lookup_read_byte_flags(offs_t address) { if constexpr(Width == 0) return lookup_read_native_flags(address & ~NATIVE_MASK); else return lookup_memory_read_generic_flags<Width, AddrShift, Endian, 0, true>(lropf(), address, 0xff); }
+ u16 lookup_read_byte_flags(offs_t address, u8 mask) { return lookup_memory_read_generic_flags<Width, AddrShift, Endian, 0, true>(lropf(), address, mask); }
u16 lookup_read_word_flags(offs_t address) { if constexpr(Width == 1) return lookup_read_native_flags(address & ~NATIVE_MASK); else return lookup_memory_read_generic_flags<Width, AddrShift, Endian, 1, true>(lropf(), address, 0xffff); }
u16 lookup_read_word_flags(offs_t address, u16 mask) { return lookup_memory_read_generic_flags<Width, AddrShift, Endian, 1, true>(lropf(), address, mask); }
u16 lookup_read_word_unaligned_flags(offs_t address) { return lookup_memory_read_generic_flags<Width, AddrShift, Endian, 1, false>(lropf(), address, 0xffff); }
@@ -1802,6 +1787,7 @@ public:
u16 lookup_read_qword_unaligned_flags(offs_t address, u64 mask) { return lookup_memory_read_generic_flags<Width, AddrShift, Endian, 3, false>(lropf(), address, mask); }
u16 lookup_write_byte_flags(offs_t address) { if constexpr(Width == 0) return lookup_write_native_flags(address & ~NATIVE_MASK); else return lookup_memory_write_generic_flags<Width, AddrShift, Endian, 0, true>(lwopf(), address, 0xff); }
+ u16 lookup_write_byte_flags(offs_t address, u8 mask) { return lookup_memory_write_generic_flags<Width, AddrShift, Endian, 0, true>(lwopf(), address, mask); }
u16 lookup_write_word_flags(offs_t address) { if constexpr(Width == 1) return lookup_write_native_flags(address & ~NATIVE_MASK); else return lookup_memory_write_generic_flags<Width, AddrShift, Endian, 1, true>(lwopf(), address, 0xffff); }
u16 lookup_write_word_flags(offs_t address, u16 mask) { return lookup_memory_write_generic_flags<Width, AddrShift, Endian, 1, true>(lwopf(), address, mask); }
u16 lookup_write_word_unaligned_flags(offs_t address) { return lookup_memory_write_generic_flags<Width, AddrShift, Endian, 1, false>(lwopf(), address, 0xffff); }
@@ -1816,11 +1802,11 @@ public:
u16 lookup_write_qword_unaligned_flags(offs_t address, u64 mask) { return lookup_memory_write_generic_flags<Width, AddrShift, Endian, 3, false>(lwopf(), address, mask); }
NativeType read_interruptible(offs_t address, NativeType mask = ~NativeType(0)) {
- return dispatch_read_interruptible<Level, Width, AddrShift>(offs_t(-1), address & m_addrmask, mask, m_dispatch_read);
+ return dispatch_read_interruptible<Level, Width, AddrShift>(~offs_t(0), address & m_addrmask, mask, m_dispatch_read);
}
void write_interruptible(offs_t address, NativeType data, NativeType mask = ~NativeType(0)) {
- dispatch_write_interruptible<Level, Width, AddrShift>(offs_t(-1), address & m_addrmask, data, mask, m_dispatch_write);
+ dispatch_write_interruptible<Level, Width, AddrShift>(~offs_t(0), address & m_addrmask, data, mask, m_dispatch_write);
}
private:
@@ -1832,27 +1818,27 @@ private:
const handler_entry_write<Width, AddrShift> *const *m_dispatch_write;
NativeType read_native(offs_t address, NativeType mask = ~NativeType(0)) {
- return dispatch_read<Level, Width, AddrShift>(offs_t(-1), address & m_addrmask, mask, m_dispatch_read);
+ return dispatch_read<Level, Width, AddrShift>(~offs_t(0), address & m_addrmask, mask, m_dispatch_read);
}
void write_native(offs_t address, NativeType data, NativeType mask = ~NativeType(0)) {
- dispatch_write<Level, Width, AddrShift>(offs_t(-1), address & m_addrmask, data, mask, m_dispatch_write);
+ dispatch_write<Level, Width, AddrShift>(~offs_t(0), address & m_addrmask, data, mask, m_dispatch_write);
}
std::pair<NativeType, u16> read_native_flags(offs_t address, NativeType mask = ~NativeType(0)) {
- return dispatch_read_flags<Level, Width, AddrShift>(offs_t(-1), address & m_addrmask, mask, m_dispatch_read);
+ return dispatch_read_flags<Level, Width, AddrShift>(~offs_t(0), address & m_addrmask, mask, m_dispatch_read);
}
u16 write_native_flags(offs_t address, NativeType data, NativeType mask = ~NativeType(0)) {
- return dispatch_write_flags<Level, Width, AddrShift>(offs_t(-1), address & m_addrmask, data, mask, m_dispatch_write);
+ return dispatch_write_flags<Level, Width, AddrShift>(~offs_t(0), address & m_addrmask, data, mask, m_dispatch_write);
}
u16 lookup_read_native_flags(offs_t address, NativeType mask = ~NativeType(0)) {
- return dispatch_lookup_read_flags<Level, Width, AddrShift>(offs_t(-1), address & m_addrmask, mask, m_dispatch_read);
+ return dispatch_lookup_read_flags<Level, Width, AddrShift>(~offs_t(0), address & m_addrmask, mask, m_dispatch_read);
}
u16 lookup_write_native_flags(offs_t address, NativeType mask = ~NativeType(0)) {
- return dispatch_lookup_write_flags<Level, Width, AddrShift>(offs_t(-1), address & m_addrmask, mask, m_dispatch_write);
+ return dispatch_lookup_write_flags<Level, Width, AddrShift>(~offs_t(0), address & m_addrmask, mask, m_dispatch_write);
}
void set(address_space *space, std::pair<const void *, const void *> rw);
@@ -1891,13 +1877,13 @@ public:
// see if an address is within bounds, update it if not
void check_address_r(offs_t address) {
- if(address >= m_addrstart_r && address <= m_addrend_r)
+ if(EXPECTED(address >= m_addrstart_r && address <= m_addrend_r))
return;
m_root_read->lookup(address, m_addrstart_r, m_addrend_r, m_cache_r);
}
void check_address_w(offs_t address) {
- if(address >= m_addrstart_w && address <= m_addrend_w)
+ if(EXPECTED(address >= m_addrstart_w && address <= m_addrend_w))
return;
m_root_write->lookup(address, m_addrstart_w, m_addrend_w, m_cache_w);
}
@@ -1922,6 +1908,7 @@ public:
auto lwopf() { return [this](offs_t offset, NativeType mask) -> u16 { return lookup_write_native_flags(offset, mask); }; }
u8 read_byte(offs_t address) { if constexpr(Width == 0) return read_native(address & ~NATIVE_MASK); else return memory_read_generic<Width, AddrShift, Endian, 0, true>(rop(), address, 0xff); }
+ u8 read_byte(offs_t address, u8 mask) { return memory_read_generic<Width, AddrShift, Endian, 0, true>(rop(), address, mask); }
u16 read_word(offs_t address) { if constexpr(Width == 1) return read_native(address & ~NATIVE_MASK); else return memory_read_generic<Width, AddrShift, Endian, 1, true>(rop(), address, 0xffff); }
u16 read_word(offs_t address, u16 mask) { return memory_read_generic<Width, AddrShift, Endian, 1, true>(rop(), address, mask); }
u16 read_word_unaligned(offs_t address) { return memory_read_generic<Width, AddrShift, Endian, 1, false>(rop(), address, 0xffff); }
@@ -1936,6 +1923,7 @@ public:
u64 read_qword_unaligned(offs_t address, u64 mask) { return memory_read_generic<Width, AddrShift, Endian, 3, false>(rop(), address, mask); }
void write_byte(offs_t address, u8 data) { if constexpr(Width == 0) write_native(address & ~NATIVE_MASK, data); else memory_write_generic<Width, AddrShift, Endian, 0, true>(wop(), address, data, 0xff); }
+ void write_byte(offs_t address, u8 data, u8 mask) { memory_write_generic<Width, AddrShift, Endian, 0, true>(wop(), address, data, mask); }
void write_word(offs_t address, u16 data) { if constexpr(Width == 1) write_native(address & ~NATIVE_MASK, data); else memory_write_generic<Width, AddrShift, Endian, 1, true>(wop(), address, data, 0xffff); }
void write_word(offs_t address, u16 data, u16 mask) { memory_write_generic<Width, AddrShift, Endian, 1, true>(wop(), address, data, mask); }
void write_word_unaligned(offs_t address, u16 data) { memory_write_generic<Width, AddrShift, Endian, 1, false>(wop(), address, data, 0xffff); }
@@ -1951,6 +1939,7 @@ public:
std::pair<u8, u16> read_byte_flags(offs_t address) { if constexpr(Width == 0) return read_native_flags(address & ~NATIVE_MASK); else return memory_read_generic_flags<Width, AddrShift, Endian, 0, true>(ropf(), address, 0xff); }
+ std::pair<u8, u16> read_byte_flags(offs_t address, u8 mask) { return memory_read_generic_flags<Width, AddrShift, Endian, 0, true>(ropf(), address, mask); }
std::pair<u16, u16> read_word_flags(offs_t address) { if constexpr(Width == 1) return read_native_flags(address & ~NATIVE_MASK); else return memory_read_generic_flags<Width, AddrShift, Endian, 1, true>(ropf(), address, 0xffff); }
std::pair<u16, u16> read_word_flags(offs_t address, u16 mask) { return memory_read_generic_flags<Width, AddrShift, Endian, 1, true>(ropf(), address, mask); }
std::pair<u16, u16> read_word_unaligned_flags(offs_t address) { return memory_read_generic_flags<Width, AddrShift, Endian, 1, false>(ropf(), address, 0xffff); }
@@ -1965,6 +1954,7 @@ public:
std::pair<u64, u16> read_qword_unaligned_flags(offs_t address, u64 mask) { return memory_read_generic_flags<Width, AddrShift, Endian, 3, false>(ropf(), address, mask); }
u16 write_byte_flags(offs_t address, u8 data) { if constexpr(Width == 0) return write_native_flags(address & ~NATIVE_MASK, data); else return memory_write_generic_flags<Width, AddrShift, Endian, 0, true>(wopf(), address, data, 0xff); }
+ u16 write_byte_flags(offs_t address, u8 data, u8 mask) { return memory_write_generic_flags<Width, AddrShift, Endian, 0, true>(wopf(), address, data, mask); }
u16 write_word_flags(offs_t address, u16 data) { if constexpr(Width == 1) return write_native_flags(address & ~NATIVE_MASK, data); else return memory_write_generic_flags<Width, AddrShift, Endian, 1, true>(wopf(), address, data, 0xffff); }
u16 write_word_flags(offs_t address, u16 data, u16 mask) { return memory_write_generic_flags<Width, AddrShift, Endian, 1, true>(wopf(), address, data, mask); }
u16 write_word_unaligned_flags(offs_t address, u16 data) { return memory_write_generic_flags<Width, AddrShift, Endian, 1, false>(wopf(), address, data, 0xffff); }
@@ -1980,6 +1970,7 @@ public:
u16 lookup_read_byte_flags(offs_t address) { if constexpr(Width == 0) return lookup_read_native_flags(address & ~NATIVE_MASK); else return lookup_memory_read_generic_flags<Width, AddrShift, Endian, 0, true>(lropf(), address, 0xff); }
+ u16 lookup_read_byte_flags(offs_t address, u8 mask) { return lookup_memory_read_generic_flags<Width, AddrShift, Endian, 0, true>(lropf(), address, mask); }
u16 lookup_read_word_flags(offs_t address) { if constexpr(Width == 1) return lookup_read_native_flags(address & ~NATIVE_MASK); else return lookup_memory_read_generic_flags<Width, AddrShift, Endian, 1, true>(lropf(), address, 0xffff); }
u16 lookup_read_word_flags(offs_t address, u16 mask) { return lookup_memory_read_generic_flags<Width, AddrShift, Endian, 1, true>(lropf(), address, mask); }
u16 lookup_read_word_unaligned_flags(offs_t address) { return lookup_memory_read_generic_flags<Width, AddrShift, Endian, 1, false>(lropf(), address, 0xffff); }
@@ -1994,6 +1985,7 @@ public:
u16 lookup_read_qword_unaligned_flags(offs_t address, u64 mask) { return lookup_memory_read_generic_flags<Width, AddrShift, Endian, 3, false>(lropf(), address, mask); }
u16 lookup_write_byte_flags(offs_t address) { if constexpr(Width == 0) return lookup_write_native_flags(address & ~NATIVE_MASK); else return lookup_memory_write_generic_flags<Width, AddrShift, Endian, 0, true>(lwopf(), address, 0xff); }
+ u16 lookup_write_byte_flags(offs_t address, u8 mask) { return lookup_memory_write_generic_flags<Width, AddrShift, Endian, 0, true>(lwopf(), address, mask); }
u16 lookup_write_word_flags(offs_t address) { if constexpr(Width == 1) return lookup_write_native_flags(address & ~NATIVE_MASK); else return lookup_memory_write_generic_flags<Width, AddrShift, Endian, 1, true>(lwopf(), address, 0xffff); }
u16 lookup_write_word_flags(offs_t address, u16 mask) { return lookup_memory_write_generic_flags<Width, AddrShift, Endian, 1, true>(lwopf(), address, mask); }
u16 lookup_write_word_unaligned_flags(offs_t address) { return lookup_memory_write_generic_flags<Width, AddrShift, Endian, 1, false>(lwopf(), address, 0xffff); }
@@ -2313,13 +2305,13 @@ protected:
void check_optimize_mirror(const char *function, offs_t addrstart, offs_t addrend, offs_t addrmirror, offs_t &nstart, offs_t &nend, offs_t &nmask, offs_t &nmirror);
void check_address(const char *function, offs_t addrstart, offs_t addrend);
- address_space_installer(const address_space_config &config, memory_manager &manager)
- : m_config(config),
- m_manager(manager),
- m_addrmask(make_bitmask<offs_t>(m_config.addr_width())),
- m_logaddrmask(make_bitmask<offs_t>(m_config.logaddr_width())),
- m_addrchars((m_config.addr_width() + 3) / 4),
- m_logaddrchars((m_config.logaddr_width() + 3) / 4)
+ address_space_installer(const address_space_config &config, memory_manager &manager) :
+ m_config(config),
+ m_manager(manager),
+ m_addrmask(make_bitmask<offs_t>(m_config.addr_width())),
+ m_logaddrmask(make_bitmask<offs_t>(m_config.logaddr_width())),
+ m_addrchars((m_config.addr_width() + 3) / 4),
+ m_logaddrchars((m_config.logaddr_width() + 3) / 4)
{}
const address_space_config &m_config; // configuration of this space
@@ -2343,6 +2335,24 @@ protected:
address_space(memory_manager &manager, device_memory_interface &memory, int spacenum);
public:
+ struct specific_access_info
+ {
+ struct side
+ {
+ void const *const *dispatch;
+ uintptr_t function;
+ ptrdiff_t displacement;
+ bool is_virtual;
+ };
+
+ unsigned native_bytes;
+ unsigned native_mask_bits;
+ unsigned address_width;
+ unsigned low_bits;
+ side read;
+ side write;
+ };
+
virtual ~address_space();
// getters
@@ -2406,12 +2416,13 @@ public:
void set_log_unmap(bool log) { m_log_unmap = log; }
// general accessors
- virtual void accessors(data_accessors &accessors) const = 0;
+ virtual specific_access_info specific_accessors() const = 0;
virtual void *get_read_ptr(offs_t address) const = 0;
virtual void *get_write_ptr(offs_t address) const = 0;
// read accessors
virtual u8 read_byte(offs_t address) = 0;
+ virtual u8 read_byte(offs_t address, u8 mask) = 0;
virtual u16 read_word(offs_t address) = 0;
virtual u16 read_word(offs_t address, u16 mask) = 0;
virtual u16 read_word_unaligned(offs_t address) = 0;
@@ -2427,6 +2438,7 @@ public:
// write accessors
virtual void write_byte(offs_t address, u8 data) = 0;
+ virtual void write_byte(offs_t address, u8 data, u8 mask) = 0;
virtual void write_word(offs_t address, u16 data) = 0;
virtual void write_word(offs_t address, u16 data, u16 mask) = 0;
virtual void write_word_unaligned(offs_t address, u16 data) = 0;
@@ -2442,7 +2454,7 @@ public:
// setup
void prepare_map();
- void prepare_device_map(address_map &map);
+ void prepare_device_map(address_map &map) ATTR_COLD;
void populate_from_map(address_map *map = nullptr);
template<int Width, int AddrShift> handler_entry_read_unmapped <Width, AddrShift> *get_unmap_r() const { return static_cast<handler_entry_read_unmapped <Width, AddrShift> *>(m_unmap_r); }
@@ -2458,7 +2470,7 @@ protected:
virtual std::pair<void *, void *> get_cache_info() = 0;
virtual std::pair<const void *, const void *> get_specific_info() = 0;
- void prepare_map_generic(address_map &map, bool allow_alloc);
+ void prepare_map_generic(address_map &map, bool allow_alloc) ATTR_COLD;
// private state
device_t & m_device; // reference to the owning device
@@ -2630,8 +2642,8 @@ public:
int m_id;
memory_view_entry(const address_space_config &config, memory_manager &manager, memory_view &view, int id);
- void prepare_map_generic(address_map &map, bool allow_alloc);
- void prepare_device_map(address_map &map);
+ void prepare_map_generic(address_map &map, bool allow_alloc) ATTR_COLD;
+ void prepare_device_map(address_map &map) ATTR_COLD;
void check_range_optimize_all(const char *function, int width, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth, offs_t &nstart, offs_t &nend, offs_t &nmask, offs_t &nmirror, u64 &nunitmask, int &ncswidth);
void check_range_optimize_mirror(const char *function, offs_t addrstart, offs_t addrend, offs_t addrmirror, offs_t &nstart, offs_t &nend, offs_t &nmask, offs_t &nmirror);
@@ -2645,13 +2657,13 @@ public:
void select(int entry);
void disable();
+ bool exists() const { return m_config != nullptr; }
std::optional<int> entry() const { return m_cur_id == -1 ? std::optional<int>() : m_cur_slot; }
const std::string &name() const { return m_name; }
private:
-
device_t & m_device;
std::string m_name;
std::map<int, int> m_entry_mapping;
@@ -2671,6 +2683,7 @@ private:
void make_subdispatch(std::string context);
int id_to_slot(int id) const;
void register_state();
+ void refresh_id();
};