diff options
Diffstat (limited to 'src/emu/emumem.h')
-rw-r--r-- | src/emu/emumem.h | 149 |
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(); }; |