diff options
Diffstat (limited to 'src/emu/emumem_heu.h')
-rw-r--r-- | src/emu/emumem_heu.h | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/src/emu/emumem_heu.h b/src/emu/emumem_heu.h new file mode 100644 index 00000000000..c7dcea23287 --- /dev/null +++ b/src/emu/emumem_heu.h @@ -0,0 +1,90 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// handler_entry_read_units/handler_entry_write_units + +// merges/splits an access among multiple handlers (unitmask support) + +template<int Width, int AddrShift, int Endian> class handler_entry_read_units : public handler_entry_read<Width, AddrShift, Endian> +{ +public: + using uX = typename handler_entry_size<Width>::uX; + using READ = typename handler_entry_size<Width>::READ; + using inh = handler_entry_read<Width, AddrShift, Endian>; + + handler_entry_read_units(const memory_units_descriptor<Width, AddrShift, Endian> &descriptor, u8 ukey, address_space *space); + handler_entry_read_units(const memory_units_descriptor<Width, AddrShift, Endian> &descriptor, u8 ukey, const handler_entry_read_units *src); + ~handler_entry_read_units(); + + uX read(offs_t offset, uX mem_mask) override; + + std::string name() const override; + + void enumerate_references(handler_entry::reflist &refs) const override; + +private: + static constexpr u32 SUBUNIT_COUNT = 1 << Width; + + struct subunit_info + { + handler_entry *m_handler; // the handler itself, the root to hide the templatization + + uX m_amask; // access mask (for filtering access) + uX m_dmask; // data mask (for removal on collisions) + s8 m_ashift; // shift to apply to the address (positive = right) + u8 m_offset; // offset to add to the address post shift + u8 m_dshift; // data shift of the subunit + + u8 m_width; // access width (0..3) + u8 m_endian; // endianness + }; + + subunit_info m_subunit_infos[SUBUNIT_COUNT]; // subunit information + uX m_unmap; // "unmapped" value to add to reads + u8 m_subunits; // number of subunits + + void fill(const memory_units_descriptor<Width, AddrShift, Endian> &descriptor, const std::vector<typename memory_units_descriptor<Width, AddrShift, Endian>::entry> &entries); + static std::string m2r(uX mask); +}; + +template<int Width, int AddrShift, int Endian> class handler_entry_write_units : public handler_entry_write<Width, AddrShift, Endian> +{ +public: + using uX = typename handler_entry_size<Width>::uX; + using WRITE = typename handler_entry_size<Width>::WRITE; + using inh = handler_entry_write<Width, AddrShift, Endian>; + + handler_entry_write_units(const memory_units_descriptor<Width, AddrShift, Endian> &descriptor, u8 ukey, address_space *space); + handler_entry_write_units(const memory_units_descriptor<Width, AddrShift, Endian> &descriptor, u8 ukey, const handler_entry_write_units<Width, AddrShift, Endian> *src); + ~handler_entry_write_units(); + + void write(offs_t offset, uX data, uX mem_mask) override; + + std::string name() const override; + + void enumerate_references(handler_entry::reflist &refs) const override; + +private: + static constexpr u32 SUBUNIT_COUNT = 1 << Width; + + struct subunit_info + { + handler_entry *m_handler; // the handler itself, the root to hide the templatization + + uX m_amask; // access mask (for filtering access) + uX m_dmask; // data mask (for removal on collisions) + s8 m_ashift; // shift to apply to the address (positive = right) + u8 m_offset; // offset to add to the address post shift + u8 m_dshift; // data shift of the subunit + + u8 m_width; // access width (0..3) + u8 m_endian; // endianness + }; + + subunit_info m_subunit_infos[SUBUNIT_COUNT]; // subunit information + u8 m_subunits; // number of subunits + + void fill(const memory_units_descriptor<Width, AddrShift, Endian> &descriptor, const std::vector<typename memory_units_descriptor<Width, AddrShift, Endian>::entry> &entries); + static std::string m2r(uX mask); +}; + |