mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00

Use standard uint64_t, uint32_t, uint16_t or uint8_t instead of UINT64, UINT32, UINT16 or UINT8 also use standard int64_t, int32_t, int16_t or int8_t instead of INT64, INT32, INT16 or INT8
250 lines
7.7 KiB
C++
250 lines
7.7 KiB
C++
// license:BSD-3-Clause
|
|
// copyright-holders:Aaron Giles
|
|
/***************************************************************************
|
|
|
|
dimemory.c
|
|
|
|
Device memory interfaces.
|
|
|
|
***************************************************************************/
|
|
|
|
#include "emu.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_t datawidth, uint8_t addrwidth, int8_t 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_t datawidth, uint8_t addrwidth, int8_t addrshift, uint8_t logwidth, uint8_t 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_t datawidth, uint8_t addrwidth, int8_t 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_t datawidth, uint8_t addrwidth, int8_t addrshift, uint8_t logwidth, uint8_t 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_t &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_t 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_t &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_t &>(device()), spacenum);
|
|
|
|
// let the map check itself
|
|
addrmap.map_validity_check(valid, device(), spacenum);
|
|
}
|
|
}
|
|
}
|