// license:BSD-3-Clause // copyright-holders:Aaron Giles /*************************************************************************** dimemory.c Device memory interfaces. ***************************************************************************/ #include "emu.h" #include "validity.h" //************************************************************************** // CONSTANTS //************************************************************************** //const int TRIGGER_SUSPENDTIME = -4000; //************************************************************************** // ADDRESS SPACE CONFIG //************************************************************************** //------------------------------------------------- // address_space_config - constructors //------------------------------------------------- address_space_config::address_space_config() : m_name("unknown"), m_endianness(ENDIANNESS_NATIVE), m_databus_width(0), m_addrbus_width(0), m_addrbus_shift(0), m_logaddr_width(0), m_page_shift(0), m_is_octal(false), m_internal_map(nullptr), m_default_map(nullptr) { } /*! @param name @param endian CPU endianness @param datawidth CPU parallelism bits @param addrwidth address bits @param addrshift @param internal @param defmap */ address_space_config::address_space_config(const char *name, endianness_t endian, UINT8 datawidth, UINT8 addrwidth, INT8 addrshift, address_map_constructor internal, address_map_constructor defmap) : m_name(name), m_endianness(endian), m_databus_width(datawidth), m_addrbus_width(addrwidth), m_addrbus_shift(addrshift), m_logaddr_width(addrwidth), m_page_shift(0), m_is_octal(false), m_internal_map(internal), m_default_map(defmap) { } address_space_config::address_space_config(const char *name, endianness_t endian, UINT8 datawidth, UINT8 addrwidth, INT8 addrshift, UINT8 logwidth, UINT8 pageshift, address_map_constructor internal, address_map_constructor defmap) : m_name(name), m_endianness(endian), m_databus_width(datawidth), m_addrbus_width(addrwidth), m_addrbus_shift(addrshift), m_logaddr_width(logwidth), m_page_shift(pageshift), m_is_octal(false), m_internal_map(internal), m_default_map(defmap) { } address_space_config::address_space_config(const char *name, endianness_t endian, UINT8 datawidth, UINT8 addrwidth, INT8 addrshift, address_map_delegate internal, address_map_delegate defmap) : m_name(name), m_endianness(endian), m_databus_width(datawidth), m_addrbus_width(addrwidth), m_addrbus_shift(addrshift), m_logaddr_width(addrwidth), m_page_shift(0), m_is_octal(false), m_internal_map(nullptr), m_default_map(nullptr), m_internal_map_delegate(std::move(internal)), m_default_map_delegate(std::move(defmap)) { } address_space_config::address_space_config(const char *name, endianness_t endian, UINT8 datawidth, UINT8 addrwidth, INT8 addrshift, UINT8 logwidth, UINT8 pageshift, address_map_delegate internal, address_map_delegate defmap) : m_name(name), m_endianness(endian), m_databus_width(datawidth), m_addrbus_width(addrwidth), m_addrbus_shift(addrshift), m_logaddr_width(logwidth), m_page_shift(pageshift), m_is_octal(false), m_internal_map(nullptr), m_default_map(nullptr), m_internal_map_delegate(std::move(internal)), m_default_map_delegate(std::move(defmap)) { } //************************************************************************** // MEMORY DEVICE MANAGEMENT //************************************************************************** //------------------------------------------------- // device_memory_interface - constructor //------------------------------------------------- device_memory_interface::device_memory_interface(const machine_config &mconfig, device_t &device) : device_interface(device, "memory") { memset(m_address_map, 0, sizeof(m_address_map)); memset(m_addrspace, 0, sizeof(m_addrspace)); // configure the fast accessor device.interfaces().m_memory = this; } //------------------------------------------------- // ~device_memory_interface - destructor //------------------------------------------------- device_memory_interface::~device_memory_interface() { } //------------------------------------------------- // static_set_addrmap - configuration helper // to connect an address map to a device //------------------------------------------------- void device_memory_interface::static_set_addrmap(device_t &device, address_spacenum spacenum, address_map_constructor map) { device_memory_interface *memory; if (!device.interface(memory)) throw emu_fatalerror("MCFG_DEVICE_ADDRESS_MAP called on device '%s' with no memory interface", device.tag()); if (spacenum >= ARRAY_LENGTH(memory->m_address_map)) throw emu_fatalerror("MCFG_DEVICE_ADDRESS_MAP called on device '%s' with out-of-range space number %d", device.tag(), spacenum); memory->m_address_map[spacenum] = map; } //------------------------------------------------- // set_address_space - connect an address space // to a device //------------------------------------------------- void device_memory_interface::set_address_space(address_spacenum spacenum, address_space &space) { assert(spacenum < ARRAY_LENGTH(m_addrspace)); m_addrspace[spacenum] = &space; } //------------------------------------------------- // memory_translate - translate from logical to // phyiscal addresses; designed to be overridden // by the actual device implementation if address // translation is supported //------------------------------------------------- bool device_memory_interface::memory_translate(address_spacenum spacenum, int intention, offs_t &address) { // by default it maps directly return true; } //------------------------------------------------- // memory_read - perform internal memory // operations that bypass the memory system; // designed to be overridden by the actual device // implementation if internal read operations are // handled by bypassing the memory system //------------------------------------------------- bool device_memory_interface::memory_read(address_spacenum spacenum, offs_t offset, int size, UINT64 &value) { // by default, we don't do anything return false; } //------------------------------------------------- // memory_write - perform internal memory // operations that bypass the memory system; // designed to be overridden by the actual device // implementation if internal write operations are // handled by bypassing the memory system //------------------------------------------------- bool device_memory_interface::memory_write(address_spacenum spacenum, offs_t offset, int size, UINT64 value) { // by default, we don't do anything return false; } //------------------------------------------------- // memory_readop - perform internal memory // operations that bypass the memory system; // designed to be overridden by the actual device // implementation if internal opcode fetching // operations are handled by bypassing the memory // system //------------------------------------------------- bool device_memory_interface::memory_readop(offs_t offset, int size, UINT64 &value) { // by default, we don't do anything return false; } //------------------------------------------------- // interface_validity_check - perform validity // checks on the memory configuration //------------------------------------------------- void device_memory_interface::interface_validity_check(validity_checker &valid) const { // loop over all address spaces for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; ++spacenum) { if (space_config(spacenum) != nullptr) { // construct the map ::address_map addrmap(const_cast(device()), spacenum); // let the map check itself addrmap.map_validity_check(valid, device(), spacenum); } } }