From 22513fb6fe281f5ccb75aaddb6417a12a66c313d Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Mon, 25 May 2020 16:42:42 +0200 Subject: emumem: A little more speedup. cache and specific change syntax, and are not pointers anymore [O. Galibert] The last(?) two changes are: - Add a template parameter to everything (theoretically the address space width, in practice a level derived from it to keep as much compatibility between widths as possible) so that the shift size becomes a constant. - Change the syntax of declaring and initializing the caches and specifics so that they're embedded in the owner device. Solves lifetime issues and also removes one indirection (looking up the base dispatch pointer through the cache/specific pointer). --- src/emu/emumem.cpp | 317 +++++++++++++++++++---------------------------------- 1 file changed, 112 insertions(+), 205 deletions(-) (limited to 'src/emu/emumem.cpp') diff --git a/src/emu/emumem.cpp b/src/emu/emumem.cpp index e0cbaf6c828..e48b13d9a51 100644 --- a/src/emu/emumem.cpp +++ b/src/emu/emumem.cpp @@ -80,103 +80,103 @@ void handler_entry::enumerate_references(handler_entry::reflist &refs) const { } -template void handler_entry_read::get_dispatch(handler_entry_read *const *&dispatch, u8 &shift) const +template const handler_entry_read *const *handler_entry_read::get_dispatch() const { fatalerror("get_dispatch called on non-dispatching class\n"); } -template void handler_entry_read::populate_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_read *handler) +template void handler_entry_read::populate_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_read *handler) { fatalerror("populate called on non-dispatching class\n"); } -template void handler_entry_read::populate_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read *handler) +template void handler_entry_read::populate_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read *handler) { fatalerror("populate called on non-dispatching class\n"); } -template void handler_entry_read::populate_mismatched_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, const memory_units_descriptor &descriptor, u8 rkey, std::vector &mappings) +template void handler_entry_read::populate_mismatched_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, const memory_units_descriptor &descriptor, u8 rkey, std::vector &mappings) { fatalerror("populate_mismatched called on non-dispatching class\n"); } -template void handler_entry_read::populate_mismatched_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, const memory_units_descriptor &descriptor, std::vector &mappings) +template void handler_entry_read::populate_mismatched_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, const memory_units_descriptor &descriptor, std::vector &mappings) { fatalerror("populate_mismatched called on non-dispatching class\n"); } -template void handler_entry_read::populate_passthrough_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_read_passthrough *handler, std::vector &mappings) +template void handler_entry_read::populate_passthrough_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_read_passthrough *handler, std::vector &mappings) { fatalerror("populate_passthrough called on non-dispatching class\n"); } -template void handler_entry_read::populate_passthrough_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read_passthrough *handler, std::vector &mappings) +template void handler_entry_read::populate_passthrough_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read_passthrough *handler, std::vector &mappings) { fatalerror("populate_passthrough called on non-dispatching class\n"); } -template void handler_entry_read::lookup(offs_t address, offs_t &start, offs_t &end, handler_entry_read *&handler) const +template void handler_entry_read::lookup(offs_t address, offs_t &start, offs_t &end, handler_entry_read *&handler) const { fatalerror("lookup called on non-dispatching class\n"); } -template void *handler_entry_read::get_ptr(offs_t offset) const +template void *handler_entry_read::get_ptr(offs_t offset) const { return nullptr; } -template void handler_entry_read::detach(const std::unordered_set &handlers) +template void handler_entry_read::detach(const std::unordered_set &handlers) { fatalerror("detach called on non-dispatching class\n"); } -template void handler_entry_write::get_dispatch(handler_entry_write *const *&dispatch, u8 &shift) const +template const handler_entry_write *const *handler_entry_write::get_dispatch() const { fatalerror("get_dispatch called on non-dispatching class\n"); } -template void handler_entry_write::populate_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_write *handler) +template void handler_entry_write::populate_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_write *handler) { fatalerror("populate called on non-dispatching class\n"); } -template void handler_entry_write::populate_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_write *handler) +template void handler_entry_write::populate_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_write *handler) { fatalerror("populate called on non-dispatching class\n"); } -template void handler_entry_write::populate_mismatched_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, const memory_units_descriptor &descriptor, u8 rkey, std::vector &mappings) +template void handler_entry_write::populate_mismatched_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, const memory_units_descriptor &descriptor, u8 rkey, std::vector &mappings) { fatalerror("populate_mismatched called on non-dispatching class\n"); } -template void handler_entry_write::populate_mismatched_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, const memory_units_descriptor &descriptor, std::vector &mappings) +template void handler_entry_write::populate_mismatched_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, const memory_units_descriptor &descriptor, std::vector &mappings) { fatalerror("populate_mismatched called on non-dispatching class\n"); } -template void handler_entry_write::populate_passthrough_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_write_passthrough *handler, std::vector &mappings) +template void handler_entry_write::populate_passthrough_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_write_passthrough *handler, std::vector &mappings) { fatalerror("populate_passthrough called on non-dispatching class\n"); } -template void handler_entry_write::populate_passthrough_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_write_passthrough *handler, std::vector &mappings) +template void handler_entry_write::populate_passthrough_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_write_passthrough *handler, std::vector &mappings) { fatalerror("populate_passthrough called on non-dispatching class\n"); } -template void handler_entry_write::lookup(offs_t address, offs_t &start, offs_t &end, handler_entry_write *&handler) const +template void handler_entry_write::lookup(offs_t address, offs_t &start, offs_t &end, handler_entry_write *&handler) const { fatalerror("lookup called on non-dispatching class\n"); } -template void *handler_entry_write::get_ptr(offs_t offset) const +template void *handler_entry_write::get_ptr(offs_t offset) const { return nullptr; } -template void handler_entry_write::detach(const std::unordered_set &handlers) +template void handler_entry_write::detach(const std::unordered_set &handlers) { fatalerror("detach called on non-dispatching class\n"); } @@ -283,12 +283,12 @@ const int MEMORY_BLOCK_CHUNK = 65536; // minimum chunk size of // ======================> address_space_specific // this is a derived class of address_space with specific width, endianness, and table size -template +template class address_space_specific : public address_space { using uX = typename emu::detail::handler_entry_size::uX; using NativeType = uX; - using this_type = address_space_specific; + using this_type = address_space_specific; // constants describing the native size static constexpr u32 NATIVE_BYTES = 1 << Width; @@ -299,10 +299,8 @@ class address_space_specific : public address_space static constexpr offs_t offset_to_byte(offs_t offset) { return AddrShift < 0 ? offset << iabs(AddrShift) : offset >> iabs(AddrShift); } public: - handler_entry_read *const *m_dispatch_read; - handler_entry_write *const *m_dispatch_write; - u8 m_shift_read; - u8 m_shift_write; + const handler_entry_read *const *m_dispatch_read; + const handler_entry_write *const *m_dispatch_write; std::string get_handler_string(read_or_write readorwrite, offs_t byteaddress) const override; void dump_maps(std::vector &read_map, std::vector &write_map) const override; @@ -519,16 +517,22 @@ public: default: fatalerror("Unhandled address bus width %d\n", address_width); } - m_root_read->get_dispatch(m_dispatch_read, m_shift_read); - m_root_write->get_dispatch(m_dispatch_write, m_shift_write); + m_dispatch_read = m_root_read ->get_dispatch(); + m_dispatch_write = m_root_write->get_dispatch(); } - void *create_cache() override { - return new memory_access_cache(*this, m_root_read, m_root_write); + std::pair get_cache_info() override { + std::pair rw; + rw.first = m_root_read; + rw.second = m_root_write; + return rw; } - void *create_specific() override { - return new memory_access_specific(*this, m_dispatch_read, m_shift_read, m_dispatch_write, m_shift_write); + std::pair get_specific_info() override { + std::pair rw; + rw.first = m_dispatch_read; + rw.second = m_dispatch_write; + return rw; } void delayed_ref(handler_entry *e) { @@ -595,25 +599,25 @@ public: // native read NativeType read_native(offs_t offset, NativeType mask) { - return dispatch_read(offs_t(-1), m_shift_read, offset & m_addrmask, mask, m_dispatch_read); + return dispatch_read(m_addrmask, offset, mask, m_dispatch_read);; } // mask-less native read NativeType read_native(offs_t offset) { - return dispatch_read(offs_t(-1), m_shift_read, offset & m_addrmask, uX(0xffffffffffffffffU), m_dispatch_read); + return dispatch_read(m_addrmask, offset, uX(0xffffffffffffffffU), m_dispatch_read); } // native write void write_native(offs_t offset, NativeType data, NativeType mask) { - dispatch_write(offs_t(-1), m_shift_write, offset & m_addrmask, data, mask, m_dispatch_write); + dispatch_write(m_addrmask, offset, data, mask, m_dispatch_write);; } // mask-less native write void write_native(offs_t offset, NativeType data) { - dispatch_write(offs_t(-1), m_shift_write, offset & m_addrmask, data, uX(0xffffffffffffffffU), m_dispatch_write); + dispatch_write(m_addrmask, offset, data, uX(0xffffffffffffffffU), m_dispatch_write);; } // virtual access to these functions @@ -907,92 +911,69 @@ void memory_manager::allocate(device_memory_interface &memory) address_space_config const *const spaceconfig = memory.space_config(spacenum); if (spaceconfig) { + int level = emu::detail::handler_entry_dispatch_level(spaceconfig->addr_width()); // allocate one of the appropriate type - switch (spaceconfig->data_width() | (spaceconfig->addr_shift() + 4)) + switch ((level << 8) | (spaceconfig->endianness() == ENDIANNESS_BIG ? 0x1000 : 0) |spaceconfig->data_width() | (spaceconfig->addr_shift() + 4)) { - case 8|(4+1): - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) - memory.allocate>(*this, spacenum); - else - memory.allocate>(*this, spacenum); - break; - - case 8|(4-0): - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) - memory.allocate>(*this, spacenum); - else - memory.allocate>(*this, spacenum); - break; - - case 16|(4+3): - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) - memory.allocate>(*this, spacenum); - else - memory.allocate>(*this, spacenum); - break; - - case 16|(4-0): - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) - memory.allocate>(*this, spacenum); - else - memory.allocate>(*this, spacenum); - break; - - case 16|(4-1): - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) - memory.allocate>(*this, spacenum); - else - memory.allocate>(*this, spacenum); - break; - - case 32|(4-0): - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) - memory.allocate>(*this, spacenum); - else - memory.allocate>(*this, spacenum); - break; - - case 32|(4-1): - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) - memory.allocate>(*this, spacenum); - else - memory.allocate>(*this, spacenum); - break; - - case 32|(4-2): - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) - memory.allocate>(*this, spacenum); - else - memory.allocate>(*this, spacenum); - break; - - case 64|(4-0): - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) - memory.allocate>(*this, spacenum); - else - memory.allocate>(*this, spacenum); - break; - - case 64|(4-1): - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) - memory.allocate>(*this, spacenum); - else - memory.allocate>(*this, spacenum); - break; - - case 64|(4-2): - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) - memory.allocate>(*this, spacenum); - else - memory.allocate>(*this, spacenum); - break; - - case 64|(4-3): - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) - memory.allocate>(*this, spacenum); - else - memory.allocate>(*this, spacenum); - break; + case 0x0000|0x000| 8|(4+1): memory.allocate>(*this, spacenum); break; + case 0x1000|0x000| 8|(4+1): memory.allocate>(*this, spacenum); break; + case 0x0000|0x100| 8|(4+1): memory.allocate>(*this, spacenum); break; + case 0x1000|0x100| 8|(4+1): memory.allocate>(*this, spacenum); break; + + case 0x0000|0x000| 8|(4-0): memory.allocate>(*this, spacenum); break; + case 0x1000|0x000| 8|(4-0): memory.allocate>(*this, spacenum); break; + case 0x0000|0x100| 8|(4-0): memory.allocate>(*this, spacenum); break; + case 0x1000|0x100| 8|(4-0): memory.allocate>(*this, spacenum); break; + + case 0x0000|0x000|16|(4+3): memory.allocate>(*this, spacenum); break; + case 0x1000|0x000|16|(4+3): memory.allocate>(*this, spacenum); break; + case 0x0000|0x100|16|(4+3): memory.allocate>(*this, spacenum); break; + case 0x1000|0x100|16|(4+3): memory.allocate>(*this, spacenum); break; + + case 0x0000|0x000|16|(4-0): memory.allocate>(*this, spacenum); break; + case 0x1000|0x000|16|(4-0): memory.allocate>(*this, spacenum); break; + case 0x0000|0x100|16|(4-0): memory.allocate>(*this, spacenum); break; + case 0x1000|0x100|16|(4-0): memory.allocate>(*this, spacenum); break; + + case 0x0000|0x000|16|(4-1): memory.allocate>(*this, spacenum); break; + case 0x1000|0x000|16|(4-1): memory.allocate>(*this, spacenum); break; + case 0x0000|0x100|16|(4-1): memory.allocate>(*this, spacenum); break; + case 0x1000|0x100|16|(4-1): memory.allocate>(*this, spacenum); break; + + case 0x0000|0x000|32|(4-0): memory.allocate>(*this, spacenum); break; + case 0x1000|0x000|32|(4-0): memory.allocate>(*this, spacenum); break; + case 0x0000|0x100|32|(4-0): memory.allocate>(*this, spacenum); break; + case 0x1000|0x100|32|(4-0): memory.allocate>(*this, spacenum); break; + + case 0x0000|0x000|32|(4-1): memory.allocate>(*this, spacenum); break; + case 0x1000|0x000|32|(4-1): memory.allocate>(*this, spacenum); break; + case 0x0000|0x100|32|(4-1): memory.allocate>(*this, spacenum); break; + case 0x1000|0x100|32|(4-1): memory.allocate>(*this, spacenum); break; + + case 0x0000|0x000|32|(4-2): memory.allocate>(*this, spacenum); break; + case 0x1000|0x000|32|(4-2): memory.allocate>(*this, spacenum); break; + case 0x0000|0x100|32|(4-2): memory.allocate>(*this, spacenum); break; + case 0x1000|0x100|32|(4-2): memory.allocate>(*this, spacenum); break; + + case 0x0000|0x000|64|(4-0): memory.allocate>(*this, spacenum); break; + case 0x1000|0x000|64|(4-0): memory.allocate>(*this, spacenum); break; + case 0x0000|0x100|64|(4-0): memory.allocate>(*this, spacenum); break; + case 0x1000|0x100|64|(4-0): memory.allocate>(*this, spacenum); break; + + case 0x0000|0x000|64|(4-1): memory.allocate>(*this, spacenum); break; + case 0x1000|0x000|64|(4-1): memory.allocate>(*this, spacenum); break; + case 0x0000|0x100|64|(4-1): memory.allocate>(*this, spacenum); break; + case 0x1000|0x100|64|(4-1): memory.allocate>(*this, spacenum); break; + + case 0x0000|0x000|64|(4-2): memory.allocate>(*this, spacenum); break; + case 0x1000|0x000|64|(4-2): memory.allocate>(*this, spacenum); break; + case 0x0000|0x100|64|(4-2): memory.allocate>(*this, spacenum); break; + case 0x1000|0x100|64|(4-2): memory.allocate>(*this, spacenum); break; + + case 0x0000|0x000|64|(4-3): memory.allocate>(*this, spacenum); break; + case 0x1000|0x000|64|(4-3): memory.allocate>(*this, spacenum); break; + case 0x0000|0x100|64|(4-3): memory.allocate>(*this, spacenum); break; + case 0x1000|0x100|64|(4-3): memory.allocate>(*this, spacenum); break; default: throw emu_fatalerror("Invalid width %d/shift %d specified for address_space::allocate", spaceconfig->data_width(), spaceconfig->addr_shift()); @@ -1885,7 +1866,7 @@ memory_passthrough_handler *address_space::install_readwrite_tap(offs_t addrstar // describing the handler at a particular offset //------------------------------------------------- -template std::string address_space_specific::get_handler_string(read_or_write readorwrite, offs_t address) const +template std::string address_space_specific::get_handler_string(read_or_write readorwrite, offs_t address) const { if (readorwrite == read_or_write::READ) { offs_t start, end; @@ -1900,7 +1881,7 @@ template std::string address_spac } } -template void address_space_specific::dump_maps(std::vector &read_map, std::vector &write_map) const +template void address_space_specific::dump_maps(std::vector &read_map, std::vector &write_map) const { read_map.clear(); write_map.clear(); @@ -1917,7 +1898,7 @@ template void address_space_speci // unmap - unmap a section of address space //------------------------------------------------- -template void address_space_specific::unmap_generic(offs_t addrstart, offs_t addrend, offs_t addrmirror, read_or_write readorwrite, bool quiet) +template void address_space_specific::unmap_generic(offs_t addrstart, offs_t addrend, offs_t addrmirror, read_or_write readorwrite, bool quiet) { VPRINTF(("address_space::unmap(%s-%s mirror=%s, %s, %s)\n", core_i64_hex_format(addrstart, m_addrchars), core_i64_hex_format(addrend, m_addrchars), @@ -1949,7 +1930,7 @@ template void address_space_speci // install_read_tap - install a read tap on the bus //------------------------------------------------- -template memory_passthrough_handler *address_space_specific::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function tap, memory_passthrough_handler *mph) +template memory_passthrough_handler *address_space_specific::install_read_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function tap, memory_passthrough_handler *mph) { offs_t nstart, nend, nmask, nmirror; check_optimize_mirror("install_read_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror); @@ -1971,7 +1952,7 @@ template memory_passthrough_handl // install_write_tap - install a write tap on the bus //------------------------------------------------- -template memory_passthrough_handler *address_space_specific::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function tap, memory_passthrough_handler *mph) +template memory_passthrough_handler *address_space_specific::install_write_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function tap, memory_passthrough_handler *mph) { offs_t nstart, nend, nmask, nmirror; check_optimize_mirror("install_write_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror); @@ -1992,7 +1973,7 @@ template memory_passthrough_handl // install_write_tap - install a read and a write tap on the bus //------------------------------------------------- -template memory_passthrough_handler *address_space_specific::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function tapr, std::function tapw, memory_passthrough_handler *mph) +template memory_passthrough_handler *address_space_specific::install_readwrite_tap(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string name, std::function tapr, std::function tapw, memory_passthrough_handler *mph) { offs_t nstart, nend, nmask, nmirror; check_optimize_mirror("install_readwrite_tap", addrstart, addrend, addrmirror, nstart, nend, nmask, nmirror); @@ -2023,7 +2004,7 @@ template memory_passthrough_handl // of a live device into this address space //------------------------------------------------- -template void address_space_specific::install_device_delegate(offs_t addrstart, offs_t addrend, device_t &device, address_map_constructor &delegate, u64 unitmask, int cswidth) +template void address_space_specific::install_device_delegate(offs_t addrstart, offs_t addrend, device_t &device, address_map_constructor &delegate, u64 unitmask, int cswidth) { check_address("install_device_delegate", addrstart, addrend); address_map map(*this, addrstart, addrend, unitmask, cswidth, m_device, delegate); @@ -2038,7 +2019,7 @@ template void address_space_speci // handler into this address space //------------------------------------------------- -template void address_space_specific::install_readwrite_port(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string rtag, std::string wtag) +template void address_space_specific::install_readwrite_port(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string rtag, std::string wtag) { VPRINTF(("address_space::install_readwrite_port(%s-%s mirror=%s, read=\"%s\" / write=\"%s\")\n", core_i64_hex_format(addrstart, m_addrchars), core_i64_hex_format(addrend, m_addrchars), @@ -2082,7 +2063,7 @@ template void address_space_speci // mapping to a particular bank //------------------------------------------------- -template void address_space_specific::install_bank_generic(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string rtag, std::string wtag) +template void address_space_specific::install_bank_generic(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string rtag, std::string wtag) { VPRINTF(("address_space::install_readwrite_bank(%s-%s mirror=%s, read=\"%s\" / write=\"%s\")\n", core_i64_hex_format(addrstart, m_addrchars), core_i64_hex_format(addrend, m_addrchars), @@ -2118,7 +2099,7 @@ template void address_space_speci } -template void address_space_specific::install_bank_generic(offs_t addrstart, offs_t addrend, offs_t addrmirror, memory_bank *rbank, memory_bank *wbank) +template void address_space_specific::install_bank_generic(offs_t addrstart, offs_t addrend, offs_t addrmirror, memory_bank *rbank, memory_bank *wbank) { VPRINTF(("address_space::install_readwrite_bank(%s-%s mirror=%s, read=\"%s\" / write=\"%s\")\n", core_i64_hex_format(addrstart, m_addrchars), core_i64_hex_format(addrend, m_addrchars), @@ -2153,7 +2134,7 @@ template void address_space_speci // RAM region into the given address space //------------------------------------------------- -template void address_space_specific::install_ram_generic(offs_t addrstart, offs_t addrend, offs_t addrmirror, read_or_write readorwrite, void *baseptr) +template void address_space_specific::install_ram_generic(offs_t addrstart, offs_t addrend, offs_t addrmirror, read_or_write readorwrite, void *baseptr) { VPRINTF(("address_space::install_ram_generic(%s-%s mirror=%s, %s, %p)\n", core_i64_hex_format(addrstart, m_addrchars), core_i64_hex_format(addrend, m_addrchars), @@ -2369,80 +2350,6 @@ memory_bank &address_space::bank_find_or_allocate(const char *tag, offs_t addrst } -//************************************************************************** -// CACHE MEMORY RANGES -//************************************************************************** - -//------------------------------------------------- -// memory_access_cache - constructor -//------------------------------------------------- - -template memory_access_cache::memory_access_cache(address_space &space, - handler_entry_read *root_read, - handler_entry_write *root_write) - : m_space(space), - m_addrmask(space.addrmask()), - m_addrstart_r(1), - m_addrend_r(0), - m_addrstart_w(1), - m_addrend_w(0), - m_cache_r(nullptr), - m_cache_w(nullptr), - m_root_read(root_read), - m_root_write(root_write) -{ - m_notifier_id = space.add_change_notifier([this](read_or_write mode) { - if(u32(mode) & u32(read_or_write::READ)) { - m_addrend_r = 0; - m_addrstart_r = 1; - m_cache_r = nullptr; - } - if(u32(mode) & u32(read_or_write::WRITE)) { - m_addrend_w = 0; - m_addrstart_w = 1; - m_cache_w = nullptr; - } - }); -} - - -//------------------------------------------------- -// ~memory_access_cache - destructor -//------------------------------------------------- - -template memory_access_cache::~memory_access_cache() -{ - m_space.remove_change_notifier(m_notifier_id); -} - - -template class memory_access_cache<0, 1, ENDIANNESS_LITTLE>; -template class memory_access_cache<0, 1, ENDIANNESS_BIG>; -template class memory_access_cache<0, 0, ENDIANNESS_LITTLE>; -template class memory_access_cache<0, 0, ENDIANNESS_BIG>; -template class memory_access_cache<1, 3, ENDIANNESS_LITTLE>; -template class memory_access_cache<1, 3, ENDIANNESS_BIG>; -template class memory_access_cache<1, 0, ENDIANNESS_LITTLE>; -template class memory_access_cache<1, 0, ENDIANNESS_BIG>; -template class memory_access_cache<1, -1, ENDIANNESS_LITTLE>; -template class memory_access_cache<1, -1, ENDIANNESS_BIG>; -template class memory_access_cache<2, 0, ENDIANNESS_LITTLE>; -template class memory_access_cache<2, 0, ENDIANNESS_BIG>; -template class memory_access_cache<2, -1, ENDIANNESS_LITTLE>; -template class memory_access_cache<2, -1, ENDIANNESS_BIG>; -template class memory_access_cache<2, -2, ENDIANNESS_LITTLE>; -template class memory_access_cache<2, -2, ENDIANNESS_BIG>; -template class memory_access_cache<3, 0, ENDIANNESS_LITTLE>; -template class memory_access_cache<3, 0, ENDIANNESS_BIG>; -template class memory_access_cache<3, -1, ENDIANNESS_LITTLE>; -template class memory_access_cache<3, -1, ENDIANNESS_BIG>; -template class memory_access_cache<3, -2, ENDIANNESS_LITTLE>; -template class memory_access_cache<3, -2, ENDIANNESS_BIG>; -template class memory_access_cache<3, -3, ENDIANNESS_LITTLE>; -template class memory_access_cache<3, -3, ENDIANNESS_BIG>; - - - //************************************************************************** // MEMORY BLOCK //************************************************************************** -- cgit v1.2.3-70-g09d2