summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2010-08-19 06:57:51 +0000
committer Aaron Giles <aaron@aarongiles.com>2010-08-19 06:57:51 +0000
commitdd19e512c03c58a100ae5025c9fd7624387667fd (patch)
tree28462fd2aa1b3a76b823d5c21ce65678085e6c8f
parentbf9afe4c4bb2112d706452c7b73bd8ebce16e3e0 (diff)
Massive memory system change. This is another step along the path toward
supporting cleaner implementations of drivers in the explicitly OO world. Expect a follow-on of several more changes to clean up from this one, which deliberately tried to avoid touching much driver code. Converted address_space to a class, and moved most members behind accessor methods, apart from space->machine and space->cpu. Removed external references to 8le/8be/16le/16be/32le/32be/64le/64be. All external access is now done via virtual functions read_byte()/read_word()/etc. Moved differentiation between the endianness and the bus width internal to memory.c, and also added a new axis to support small/large address spaces, which allows for faster lookups on spaces smaller than 18 bits. Provided methods for most global memory operations within the new address_space class. These will be bulk converted in a future update, but for now there are inline wrappers to hide this change from existing callers. Created new module delegate.h which implements C++ delegates in a form that works for MAME. Details are in the opening comment. Delegates allow member functions of certain classes to be used as callbacks, which will hopefully be the beginning of the end of fetching the driver_data field in most callbacks. All classes that host delegates must derive from bindable_object. Today, all devices and driver_data do implicitly via their base class. Defined delegates for read/write handlers. The new delegates are always passed an address_space reference, along with offset, data, and mask. Delegates can refer to methods either in the driver_data class or in a device class. To specify a callback in an address map, just use AM_READ_MEMBER(class, member). In fact, all existing AM_ macros that take read/write handlers can now accept delegates in their place. Delegates that are specified in an address map are proto-delegates which have no object; they are bound to their object when the corresponding address_space is created. Added machine->m_nonspecific_space which can be passed as the required address_space parameter to the new read/write methods in legacy situations where the space is not provided. Eventually this can go away but we will need it for a while yet. Added methods to the new address_space class to dynamically install delegates just like you can dynamically install handlers today. Delegates installed this way must be pre-bound to their object. Moved beathead's read/write handlers into members of beathead_state as an example of using the new delegates. This provides examples of both static (via an address_map) and dynamic (via install_handler calls) mapping using delegates. Added read/write member functions to okim6295_device as an example of using delegates to call devices. Updated audio/williams.c as a single example of calling the device via its member function callbacks. These will be bulk updated in a future update, and the old global callbacks removed. Changed the DIRECT_UPDATE_CALLBACKs into delegates as well. Updated all users to the new function format. Added methods on direct_read_data for configuring the parameters in a standard way to make the implementation clearer. Created a simple_list template container class for managing the common singly-linked lists we use all over in the project. Many other internal changes in memory.c, mostly involving restructuring the code into proper classes.
-rw-r--r--.gitattributes2
-rw-r--r--src/emu/addrmap.c667
-rw-r--r--src/emu/addrmap.h326
-rw-r--r--src/emu/cpu/drcbex64.c5
-rw-r--r--src/emu/cpu/drcbex86.c43
-rw-r--r--src/emu/cpu/dsp56k/dsp56k.c8
-rw-r--r--src/emu/cpu/mips/mips3com.c2
-rw-r--r--src/emu/cpu/mips/r3000.c9
-rw-r--r--src/emu/debug/debugcmd.c74
-rw-r--r--src/emu/debug/debugcmt.c4
-rw-r--r--src/emu/debug/debugcpu.c291
-rw-r--r--src/emu/debug/debugcpu.h2
-rw-r--r--src/emu/debug/dvdisasm.c44
-rw-r--r--src/emu/debug/dvmemory.c20
-rw-r--r--src/emu/delegate.c97
-rw-r--r--src/emu/delegate.h1209
-rw-r--r--src/emu/devcpu.c2
-rw-r--r--src/emu/devintrf.h2
-rw-r--r--src/emu/dimemory.c32
-rw-r--r--src/emu/dimemory.h50
-rw-r--r--src/emu/emu.h1
-rw-r--r--src/emu/emu.mak1
-rw-r--r--src/emu/emucore.h94
-rw-r--r--src/emu/machine.c2
-rw-r--r--src/emu/machine.h5
-rw-r--r--src/emu/machine/generic.c6
-rw-r--r--src/emu/machine/idectrl.c2
-rw-r--r--src/emu/memory.c6642
-rw-r--r--src/emu/memory.h1310
-rw-r--r--src/emu/sound/okim6295.c32
-rw-r--r--src/emu/sound/okim6295.h19
-rw-r--r--src/mame/audio/williams.c2
-rw-r--r--src/mame/drivers/atarig42.c16
-rw-r--r--src/mame/drivers/atarisy2.c11
-rw-r--r--src/mame/drivers/beathead.c169
-rw-r--r--src/mame/drivers/cps3.c23
-rw-r--r--src/mame/drivers/hng64.c8
-rw-r--r--src/mame/drivers/missile.c9
-rw-r--r--src/mame/drivers/plygonet.c15
-rw-r--r--src/mame/drivers/starwars.c9
-rw-r--r--src/mame/drivers/vcombat.c18
-rw-r--r--src/mame/drivers/vegas.c11
-rw-r--r--src/mame/includes/beathead.h88
-rw-r--r--src/mame/includes/plygonet.h2
-rw-r--r--src/mame/machine/archimds.c20
-rw-r--r--src/mame/machine/atarigen.c12
-rw-r--r--src/mame/machine/fddebug.c2
-rw-r--r--src/mame/machine/n64.c2
-rw-r--r--src/mame/machine/snes.c40
-rw-r--r--src/mame/video/beathead.c80
50 files changed, 6634 insertions, 4906 deletions
diff --git a/.gitattributes b/.gitattributes
index d91621e511c..08c60fe356d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -575,6 +575,8 @@ src/emu/debugger.c svneol=native#text/plain
src/emu/debugger.h svneol=native#text/plain
src/emu/debugint/debugint.c svneol=native#text/plain
src/emu/debugint/debugint.h svneol=native#text/plain
+src/emu/delegate.c svneol=native#text/plain
+src/emu/delegate.h svneol=native#text/plain
src/emu/deprecat.h svneol=native#text/plain
src/emu/devcb.c svneol=native#text/plain
src/emu/devcb.h svneol=native#text/plain
diff --git a/src/emu/addrmap.c b/src/emu/addrmap.c
index 650072bdbd6..ea44d804bf7 100644
--- a/src/emu/addrmap.c
+++ b/src/emu/addrmap.c
@@ -41,31 +41,22 @@
//**************************************************************************
-// MACROS
+// ADDRESS MAP ENTRY
//**************************************************************************
-// maps a full 64-bit mask down to an 8-bit byte mask
-#define UNITMASK8(x) \
- ((((UINT64)(x) >> (63-7)) & 0x80) | \
- (((UINT64)(x) >> (55-6)) & 0x40) | \
- (((UINT64)(x) >> (47-5)) & 0x20) | \
- (((UINT64)(x) >> (39-4)) & 0x10) | \
- (((UINT64)(x) >> (31-3)) & 0x08) | \
- (((UINT64)(x) >> (23-2)) & 0x04) | \
- (((UINT64)(x) >> (15-1)) & 0x02) | \
- (((UINT64)(x) >> ( 7-0)) & 0x01))
-
-// maps a full 64-bit mask down to a 4-bit word mask
-#define UNITMASK16(x) \
- ((((UINT64)(x) >> (63-3)) & 0x08) | \
- (((UINT64)(x) >> (47-2)) & 0x04) | \
- (((UINT64)(x) >> (31-1)) & 0x02) | \
- (((UINT64)(x) >> (15-0)) & 0x01))
+//-------------------------------------------------
+// set_tag - set the appropriate tag for a device
+//-------------------------------------------------
-// maps a full 64-bit mask down to a 2-bit dword mask
-#define UNITMASK32(x) \
- ((((UINT64)(x) >> (63-1)) & 0x02) | \
- (((UINT64)(x) >> (31-0)) & 0x01))
+inline void map_handler_data::set_tag(const device_config &devconfig, const char *tag)
+{
+ if (tag == NULL)
+ m_tag = NULL;
+ else if (strcmp(tag, DEVICE_SELF) == 0)
+ m_tag = devconfig.tag();
+ else
+ m_tag = devconfig.siblingtag(m_derived_tag, tag);
+}
@@ -93,6 +84,22 @@ address_map_entry::address_map_entry(address_map &map, offs_t start, offs_t end)
m_gensizeptroffs_plus1(0),
m_region(NULL),
m_rgnoffs(0),
+ m_rspace8(NULL),
+ m_rspace16(NULL),
+ m_rspace32(NULL),
+ m_rspace64(NULL),
+ m_rdevice8(NULL),
+ m_rdevice16(NULL),
+ m_rdevice32(NULL),
+ m_rdevice64(NULL),
+ m_wspace8(NULL),
+ m_wspace16(NULL),
+ m_wspace32(NULL),
+ m_wspace64(NULL),
+ m_wdevice8(NULL),
+ m_wdevice16(NULL),
+ m_wdevice32(NULL),
+ m_wdevice64(NULL),
m_memory(NULL),
m_bytestart(0),
m_byteend(0),
@@ -121,8 +128,8 @@ void address_map_entry::set_mask(offs_t _mask)
void address_map_entry::set_read_port(const device_config &devconfig, const char *tag)
{
- m_read.type = AMH_PORT;
- m_read.tag = devconfig.siblingtag(m_read.derived_tag, tag);
+ m_read.m_type = AMH_PORT;
+ m_read.set_tag(devconfig, tag);
}
@@ -133,8 +140,8 @@ void address_map_entry::set_read_port(const device_config &devconfig, const char
void address_map_entry::set_write_port(const device_config &devconfig, const char *tag)
{
- m_write.type = AMH_PORT;
- m_write.tag = devconfig.siblingtag(m_write.derived_tag, tag);
+ m_write.m_type = AMH_PORT;
+ m_write.set_tag(devconfig, tag);
}
@@ -145,10 +152,10 @@ void address_map_entry::set_write_port(const device_config &devconfig, const cha
void address_map_entry::set_readwrite_port(const device_config &devconfig, const char *tag)
{
- m_read.type = AMH_PORT;
- m_read.tag = devconfig.siblingtag(m_read.derived_tag, tag);
- m_write.type = AMH_PORT;
- m_write.tag = devconfig.siblingtag(m_write.derived_tag, tag);
+ m_read.m_type = AMH_PORT;
+ m_read.set_tag(devconfig, tag);
+ m_write.m_type = AMH_PORT;
+ m_write.set_tag(devconfig, tag);
}
@@ -159,8 +166,8 @@ void address_map_entry::set_readwrite_port(const device_config &devconfig, const
void address_map_entry::set_read_bank(const device_config &devconfig, const char *tag)
{
- m_read.type = AMH_BANK;
- m_read.tag = devconfig.siblingtag(m_read.derived_tag, tag);
+ m_read.m_type = AMH_BANK;
+ m_read.set_tag(devconfig, tag);
}
@@ -171,8 +178,8 @@ void address_map_entry::set_read_bank(const device_config &devconfig, const char
void address_map_entry::set_write_bank(const device_config &devconfig, const char *tag)
{
- m_write.type = AMH_BANK;
- m_write.tag = devconfig.siblingtag(m_write.derived_tag, tag);
+ m_write.m_type = AMH_BANK;
+ m_write.set_tag(devconfig, tag);
}
@@ -183,10 +190,10 @@ void address_map_entry::set_write_bank(const device_config &devconfig, const cha
void address_map_entry::set_readwrite_bank(const device_config &devconfig, const char *tag)
{
- m_read.type = AMH_BANK;
- m_read.tag = devconfig.siblingtag(m_read.derived_tag, tag);
- m_write.type = AMH_BANK;
- m_write.tag = devconfig.siblingtag(m_write.derived_tag, tag);
+ m_read.m_type = AMH_BANK;
+ m_read.set_tag(devconfig, tag);
+ m_write.m_type = AMH_BANK;
+ m_write.set_tag(devconfig, tag);
}
@@ -197,23 +204,25 @@ void address_map_entry::set_readwrite_bank(const device_config &devconfig, const
void address_map_entry::internal_set_handler(read8_space_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(8, unitmask, string));
- m_read.type = AMH_HANDLER;
- m_read.bits = (unitmask == 0) ? 0 : 8;
- m_read.mask = UNITMASK8(unitmask);
- m_read.handler.read.shandler8 = func;
- m_read.name = string;
+ m_read.m_type = AMH_LEGACY_SPACE_HANDLER;
+ m_read.m_bits = 8;
+ m_read.m_mask = unitmask;
+ m_read.m_name = string;
+ m_rspace8 = func;
}
void address_map_entry::internal_set_handler(write8_space_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(8, unitmask, string));
- m_write.type = AMH_HANDLER;
- m_write.bits = (unitmask == 0) ? 0 : 8;
- m_write.mask = UNITMASK8(unitmask);
- m_write.handler.write.shandler8 = func;
- m_write.name = string;
+ m_write.m_type = AMH_LEGACY_SPACE_HANDLER;
+ m_write.m_bits = 8;
+ m_write.m_mask = unitmask;
+ m_write.m_name = string;
+ m_wspace8 = func;
}
@@ -226,25 +235,27 @@ void address_map_entry::internal_set_handler(read8_space_func rfunc, const char
void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, read8_device_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(8, unitmask, string));
- m_read.type = AMH_DEVICE_HANDLER;
- m_read.bits = (unitmask == 0) ? 0 : 8;
- m_read.mask = UNITMASK8(unitmask);
- m_read.handler.read.dhandler8 = func;
- m_read.name = string;
- m_read.tag = devconfig.siblingtag(m_read.derived_tag, tag);
+ m_read.m_type = AMH_LEGACY_DEVICE_HANDLER;
+ m_read.m_bits = 8;
+ m_read.m_mask = unitmask;
+ m_read.m_name = string;
+ m_read.set_tag(devconfig, tag);
+ m_rdevice8 = func;
}
void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, write8_device_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(8, unitmask, string));
- m_write.type = AMH_DEVICE_HANDLER;
- m_write.bits = (unitmask == 0) ? 0 : 8;
- m_write.mask = UNITMASK8(unitmask);
- m_write.handler.write.dhandler8 = func;
- m_write.name = string;
- m_write.tag = devconfig.siblingtag(m_write.derived_tag, tag);
+ m_write.m_type = AMH_LEGACY_DEVICE_HANDLER;
+ m_write.m_bits = 8;
+ m_write.m_mask = unitmask;
+ m_write.m_name = string;
+ m_write.set_tag(devconfig, tag);
+ m_wdevice8 = func;
}
@@ -255,6 +266,39 @@ void address_map_entry::internal_set_handler(const device_config &devconfig, con
}
+void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, read8_proto_delegate func, UINT64 unitmask)
+{
+ assert(!func.isnull());
+ assert(unitmask_is_appropriate(8, unitmask, func.name()));
+ m_read.m_type = (tag == NULL) ? AMH_DRIVER_DELEGATE : AMH_DEVICE_DELEGATE;
+ m_read.m_bits = 8;
+ m_read.m_mask = unitmask;
+ m_read.m_name = func.name();
+ m_read.set_tag(devconfig, tag);
+ m_rproto8 = func;
+}
+
+
+void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, write8_proto_delegate func, UINT64 unitmask)
+{
+ assert(!func.isnull());
+ assert(unitmask_is_appropriate(8, unitmask, func.name()));
+ m_write.m_type = (tag == NULL) ? AMH_DRIVER_DELEGATE : AMH_DEVICE_DELEGATE;;
+ m_write.m_bits = 8;
+ m_write.m_mask = unitmask;
+ m_write.m_name = func.name();
+ m_write.set_tag(devconfig, tag);
+ m_wproto8 = func;
+}
+
+
+void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, read8_proto_delegate rfunc, write8_proto_delegate wfunc, UINT64 unitmask)
+{
+ internal_set_handler(devconfig, tag, rfunc, unitmask);
+ internal_set_handler(devconfig, tag, wfunc, unitmask);
+}
+
+
//-------------------------------------------------
// internal_set_handler - handler setters for
// 16-bit read/write handlers
@@ -262,23 +306,25 @@ void address_map_entry::internal_set_handler(const device_config &devconfig, con
void address_map_entry::internal_set_handler(read16_space_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(16, unitmask, string));
- m_read.type = AMH_HANDLER;
- m_read.bits = (unitmask == 0) ? 0 : 16;
- m_read.mask = UNITMASK16(unitmask);
- m_read.handler.read.shandler16 = func;
- m_read.name = string;
+ m_read.m_type = AMH_LEGACY_SPACE_HANDLER;
+ m_read.m_bits = 16;
+ m_read.m_mask = unitmask;
+ m_read.m_name = string;
+ m_rspace16 = func;
}
void address_map_entry::internal_set_handler(write16_space_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(16, unitmask, string));
- m_write.type = AMH_HANDLER;
- m_write.bits = (unitmask == 0) ? 0 : 16;
- m_write.mask = UNITMASK16(unitmask);
- m_write.handler.write.shandler16 = func;
- m_write.name = string;
+ m_write.m_type = AMH_LEGACY_SPACE_HANDLER;
+ m_write.m_bits = 16;
+ m_write.m_mask = unitmask;
+ m_write.m_name = string;
+ m_wspace16 = func;
}
@@ -291,25 +337,27 @@ void address_map_entry::internal_set_handler(read16_space_func rfunc, const char
void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, read16_device_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(16, unitmask, string));
- m_read.type = AMH_DEVICE_HANDLER;
- m_read.bits = (unitmask == 0) ? 0 : 16;
- m_read.mask = UNITMASK16(unitmask);
- m_read.handler.read.dhandler16 = func;
- m_read.name = string;
- m_read.tag = devconfig.siblingtag(m_read.derived_tag, tag);
+ m_read.m_type = AMH_LEGACY_DEVICE_HANDLER;
+ m_read.m_bits = 16;
+ m_read.m_mask = unitmask;
+ m_read.m_name = string;
+ m_read.set_tag(devconfig, tag);
+ m_rdevice16 = func;
}
void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, write16_device_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(16, unitmask, string));
- m_write.type = AMH_DEVICE_HANDLER;
- m_write.bits = (unitmask == 0) ? 0 : 16;
- m_write.mask = UNITMASK16(unitmask);
- m_write.handler.write.dhandler16 = func;
- m_write.name = string;
- m_write.tag = devconfig.siblingtag(m_write.derived_tag, tag);
+ m_write.m_type = AMH_LEGACY_DEVICE_HANDLER;
+ m_write.m_bits = 16;
+ m_write.m_mask = unitmask;
+ m_write.m_name = string;
+ m_write.set_tag(devconfig, tag);
+ m_wdevice16 = func;
}
@@ -320,6 +368,39 @@ void address_map_entry::internal_set_handler(const device_config &devconfig, con
}
+void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, read16_proto_delegate func, UINT64 unitmask)
+{
+ assert(!func.isnull());
+ assert(unitmask_is_appropriate(16, unitmask, func.name()));
+ m_read.m_type = (tag == NULL) ? AMH_DRIVER_DELEGATE : AMH_DEVICE_DELEGATE;;
+ m_read.m_bits = 16;
+ m_read.m_mask = unitmask;
+ m_read.m_name = func.name();
+ m_read.set_tag(devconfig, tag);
+ m_rproto16 = func;
+}
+
+
+void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, write16_proto_delegate func, UINT64 unitmask)
+{
+ assert(!func.isnull());
+ assert(unitmask_is_appropriate(16, unitmask, func.name()));
+ m_write.m_type = (tag == NULL) ? AMH_DRIVER_DELEGATE : AMH_DEVICE_DELEGATE;;
+ m_write.m_bits = 16;
+ m_write.m_mask = unitmask;
+ m_write.m_name = func.name();
+ m_write.set_tag(devconfig, tag);
+ m_wproto16 = func;
+}
+
+
+void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, read16_proto_delegate rfunc, write16_proto_delegate wfunc, UINT64 unitmask)
+{
+ internal_set_handler(devconfig, tag, rfunc, unitmask);
+ internal_set_handler(devconfig, tag, wfunc, unitmask);
+}
+
+
//-------------------------------------------------
// internal_set_handler - handler setters for
// 32-bit read/write handlers
@@ -327,23 +408,25 @@ void address_map_entry::internal_set_handler(const device_config &devconfig, con
void address_map_entry::internal_set_handler(read32_space_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(32, unitmask, string));
- m_read.type = AMH_HANDLER;
- m_read.bits = (unitmask == 0) ? 0 : 32;
- m_read.mask = UNITMASK32(unitmask);
- m_read.handler.read.shandler32 = func;
- m_read.name = string;
+ m_read.m_type = AMH_LEGACY_SPACE_HANDLER;
+ m_read.m_bits = 32;
+ m_read.m_mask = unitmask;
+ m_read.m_name = string;
+ m_rspace32 = func;
}
void address_map_entry::internal_set_handler(write32_space_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(32, unitmask, string));
- m_write.type = AMH_HANDLER;
- m_write.bits = (unitmask == 0) ? 0 : 32;
- m_write.mask = UNITMASK32(unitmask);
- m_write.handler.write.shandler32 = func;
- m_write.name = string;
+ m_write.m_type = AMH_LEGACY_SPACE_HANDLER;
+ m_write.m_bits = 32;
+ m_write.m_mask = unitmask;
+ m_write.m_name = string;
+ m_wspace32 = func;
}
@@ -356,25 +439,27 @@ void address_map_entry::internal_set_handler(read32_space_func rfunc, const char
void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, read32_device_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(32, unitmask, string));
- m_read.type = AMH_DEVICE_HANDLER;
- m_read.bits = (unitmask == 0) ? 0 : 32;
- m_read.mask = UNITMASK32(unitmask);
- m_read.handler.read.dhandler32 = func;
- m_read.name = string;
- m_read.tag = devconfig.siblingtag(m_read.derived_tag, tag);
+ m_read.m_type = AMH_LEGACY_DEVICE_HANDLER;
+ m_read.m_bits = 32;
+ m_read.m_mask = unitmask;
+ m_read.m_name = string;
+ m_read.set_tag(devconfig, tag);
+ m_rdevice32 = func;
}
void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, write32_device_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(32, unitmask, string));
- m_write.type = AMH_DEVICE_HANDLER;
- m_write.bits = (unitmask == 0) ? 0 : 32;
- m_write.mask = UNITMASK32(unitmask);
- m_write.handler.write.dhandler32 = func;
- m_write.name = string;
- m_write.tag = devconfig.siblingtag(m_write.derived_tag, tag);
+ m_write.m_type = AMH_LEGACY_DEVICE_HANDLER;
+ m_write.m_bits = 32;
+ m_write.m_mask = unitmask;
+ m_write.m_name = string;
+ m_write.set_tag(devconfig, tag);
+ m_wdevice32 = func;
}
@@ -385,6 +470,39 @@ void address_map_entry::internal_set_handler(const device_config &devconfig, con
}
+void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, read32_proto_delegate func, UINT64 unitmask)
+{
+ assert(!func.isnull());
+ assert(unitmask_is_appropriate(32, unitmask, func.name()));
+ m_read.m_type = (tag == NULL) ? AMH_DRIVER_DELEGATE : AMH_DEVICE_DELEGATE;;
+ m_read.m_bits = 32;
+ m_read.m_mask = unitmask;
+ m_read.m_name = func.name();
+ m_read.set_tag(devconfig, tag);
+ m_rproto32 = func;
+}
+
+
+void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, write32_proto_delegate func, UINT64 unitmask)
+{
+ assert(!func.isnull());
+ assert(unitmask_is_appropriate(32, unitmask, func.name()));
+ m_write.m_type = (tag == NULL) ? AMH_DRIVER_DELEGATE : AMH_DEVICE_DELEGATE;;
+ m_write.m_bits = 32;
+ m_write.m_mask = unitmask;
+ m_write.m_name = func.name();
+ m_write.set_tag(devconfig, tag);
+ m_wproto32 = func;
+}
+
+
+void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, read32_proto_delegate rfunc, write32_proto_delegate wfunc, UINT64 unitmask)
+{
+ internal_set_handler(devconfig, tag, rfunc, unitmask);
+ internal_set_handler(devconfig, tag, wfunc, unitmask);
+}
+
+
//-------------------------------------------------
// internal_set_handler - handler setters for
// 64-bit read/write handlers
@@ -392,23 +510,25 @@ void address_map_entry::internal_set_handler(const device_config &devconfig, con
void address_map_entry::internal_set_handler(read64_space_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(64, unitmask, string));
- m_read.type = AMH_HANDLER;
- m_read.bits = (unitmask == 0) ? 0 : 64;
- m_read.mask = 0;
- m_read.handler.read.shandler64 = func;
- m_read.name = string;
+ m_read.m_type = AMH_LEGACY_SPACE_HANDLER;
+ m_read.m_bits = 64;
+ m_read.m_mask = 0;
+ m_read.m_name = string;
+ m_rspace64 = func;
}
void address_map_entry::internal_set_handler(write64_space_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(64, unitmask, string));
- m_write.type = AMH_HANDLER;
- m_write.bits = (unitmask == 0) ? 0 : 64;
- m_write.mask = 0;
- m_write.handler.write.shandler64 = func;
- m_write.name = string;
+ m_write.m_type = AMH_LEGACY_SPACE_HANDLER;
+ m_write.m_bits = 64;
+ m_write.m_mask = 0;
+ m_write.m_name = string;
+ m_wspace64 = func;
}
@@ -421,25 +541,27 @@ void address_map_entry::internal_set_handler(read64_space_func rfunc, const char
void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, read64_device_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(64, unitmask, string));
- m_read.type = AMH_DEVICE_HANDLER;
- m_read.bits = (unitmask == 0) ? 0 : 64;
- m_read.mask = 0;
- m_read.handler.read.dhandler64 = func;
- m_read.name = string;
- m_read.tag = devconfig.siblingtag(m_read.derived_tag, tag);
+ m_read.m_type = AMH_LEGACY_DEVICE_HANDLER;
+ m_read.m_bits = 64;
+ m_read.m_mask = 0;
+ m_read.m_name = string;
+ m_read.set_tag(devconfig, tag);
+ m_rdevice64 = func;
}
void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, write64_device_func func, const char *string, UINT64 unitmask)
{
+ assert(func != NULL);
assert(unitmask_is_appropriate(64, unitmask, string));
- m_write.type = AMH_DEVICE_HANDLER;
- m_write.bits = (unitmask == 0) ? 0 : 64;
- m_write.mask = 0;
- m_write.handler.write.dhandler64 = func;
- m_write.name = string;
- m_write.tag = devconfig.siblingtag(m_write.derived_tag, tag);
+ m_write.m_type = AMH_LEGACY_DEVICE_HANDLER;
+ m_write.m_bits = 64;
+ m_write.m_mask = 0;
+ m_write.m_name = string;
+ m_write.set_tag(devconfig, tag);
+ m_wdevice64 = func;
}
@@ -450,6 +572,39 @@ void address_map_entry::internal_set_handler(const device_config &devconfig, con
}
+void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, read64_proto_delegate func, UINT64 unitmask)
+{
+ assert(!func.isnull());
+ assert(unitmask_is_appropriate(64, unitmask, func.name()));
+ m_read.m_type = (tag == NULL) ? AMH_DRIVER_DELEGATE : AMH_DEVICE_DELEGATE;;
+ m_read.m_bits = 64;
+ m_read.m_mask = 0;
+ m_read.m_name = func.name();
+ m_read.set_tag(devconfig, tag);
+ m_rproto64 = func;
+}
+
+
+void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, write64_proto_delegate func, UINT64 unitmask)
+{
+ assert(!func.isnull());
+ assert(unitmask_is_appropriate(64, unitmask, func.name()));
+ m_write.m_type = (tag == NULL) ? AMH_DRIVER_DELEGATE : AMH_DEVICE_DELEGATE;;
+ m_write.m_bits = 64;
+ m_write.m_mask = 0;
+ m_write.m_name = func.name();
+ m_write.set_tag(devconfig, tag);
+ m_wproto64 = func;
+}
+
+
+void address_map_entry::internal_set_handler(const device_config &devconfig, const char *tag, read64_proto_delegate rfunc, write64_proto_delegate wfunc, UINT64 unitmask)
+{
+ internal_set_handler(devconfig, tag, rfunc, unitmask);
+ internal_set_handler(devconfig, tag, wfunc, unitmask);
+}
+
+
//-------------------------------------------------
// unitmask_is_appropriate - verify that the
// provided unitmask is valid and expected
@@ -540,9 +695,7 @@ address_map::address_map(const device_config &devconfig, int spacenum)
: m_spacenum(spacenum),
m_databits(0xff),
m_unmapval(0),
- m_globalmask(0),
- m_entrylist(NULL),
- m_tailptr(&m_entrylist)
+ m_globalmask(0)
{
// get our memory interface
const device_config_memory_interface *memintf;
@@ -574,13 +727,6 @@ address_map::address_map(const device_config &devconfig, int spacenum)
address_map::~address_map()
{
- // free all entries */
- while (m_entrylist != NULL)
- {
- address_map_entry *entry = m_entrylist;
- m_entrylist = entry->m_next;
- global_free(entry);
- }
}
@@ -621,8 +767,7 @@ void address_map::set_global_mask(offs_t mask)
address_map_entry8 *address_map::add(offs_t start, offs_t end, address_map_entry8 *ptr)
{
ptr = global_alloc(address_map_entry8(*this, start, end));
- *m_tailptr = ptr;
- m_tailptr = &ptr->m_next;
+ m_entrylist.append(*ptr);
return ptr;
}
@@ -630,8 +775,7 @@ address_map_entry8 *address_map::add(offs_t start, offs_t end, address_map_entry
address_map_entry16 *address_map::add(offs_t start, offs_t end, address_map_entry16 *ptr)
{
ptr = global_alloc(address_map_entry16(*this, start, end));
- *m_tailptr = ptr;
- m_tailptr = &ptr->m_next;
+ m_entrylist.append(*ptr);
return ptr;
}
@@ -639,8 +783,7 @@ address_map_entry16 *address_map::add(offs_t start, offs_t end, address_map_entr
address_map_entry32 *address_map::add(offs_t start, offs_t end, address_map_entry32 *ptr)
{
ptr = global_alloc(address_map_entry32(*this, start, end));
- *m_tailptr = ptr;
- m_tailptr = &ptr->m_next;
+ m_entrylist.append(*ptr);
return ptr;
}
@@ -648,244 +791,6 @@ address_map_entry32 *address_map::add(offs_t start, offs_t end, address_map_entr
address_map_entry64 *address_map::add(offs_t start, offs_t end, address_map_entry64 *ptr)
{
ptr = global_alloc(address_map_entry64(*this, start, end));
- *m_tailptr = ptr;
- m_tailptr = &ptr->m_next;
+ m_entrylist.append(*ptr);
return ptr;
}
-
-
-
-#if 0
-
-// old code for reference
-
-/***************************************************************************
- ADDRESS MAP HELPERS
-***************************************************************************/
-
-/*-------------------------------------------------
- map_detokenize - detokenize an array of
- address map tokens
--------------------------------------------------*/
-
-#define check_map(field) do { \
- if (map->field != 0 && map->field != tmap.field) \
- fatalerror("%s: %s included a mismatched address map (%s %d) for an existing map with %s %d!\n", driver->source_file, driver->name, #field, tmap.field, #field, map->field); \
- } while (0)
-
-#define check_entry_handler(row) do { \
- if (entry->row.type != AMH_NONE) \
- fatalerror("%s: %s AM_RANGE(0x%x, 0x%x) %s handler already set!\n", driver->source_file, driver->name, entry->addrstart, entry->addrend, #row); \
- } while (0)
-
-#define check_entry_field(field) do { \
- if (entry->field != 0) \
- fatalerror("%s: %s AM_RANGE(0x%x, 0x%x) setting %s already set!\n", driver->source_file, driver->name, entry->addrstart, entry->addrend, #field); \
- } while (0)
-
-static void map_detokenize(memory_private *memdata, address_map *map, const game_driver *driver, const device_config *devconfig, const addrmap_token *tokens)
-{
- address_map_entry **firstentryptr;
- address_map_entry **entryptr;
- address_map_entry *entry;
- address_map tmap = {0};
- UINT32 entrytype;
- int maptype;
-
- /* check the first token */
- TOKEN_GET_UINT32_UNPACK3(tokens, entrytype, 8, tmap.spacenum, 8, tmap.databits, 8);
- if (entrytype != ADDRMAP_TOKEN_START)
- fatalerror("%s: %s Address map missing ADDRMAP_TOKEN_START!\n", driver->source_file, driver->name);
- if (tmap.spacenum >= ADDRESS_SPACES)
- fatalerror("%s: %s Invalid address space %d for memory map!\n", driver->source_file, driver->name, tmap.spacenum);
- if (tmap.databits != 8 && tmap.databits != 16 && tmap.databits != 32 && tmap.databits != 64)
- fatalerror("%s: %s Invalid data bits %d for memory map!\n", driver->source_file, driver->name, tmap.databits);
- check_map(spacenum);
- check_map(databits);
-
- /* fill in the map values */
- map->spacenum = tmap.spacenum;
- map->databits = tmap.databits;
-
- /* find the end of the list */
- for (entryptr = &map->entrylist; *entryptr != NULL; entryptr = &(*entryptr)->next) ;
- firstentryptr = entryptr;
- entry = NULL;
-
- /* loop over tokens until we hit the end */
- while (entrytype != ADDRMAP_TOKEN_END)
- {
- /* unpack the token from the first entry */
- TOKEN_GET_UINT32_UNPACK1(tokens, entrytype, 8);
- switch (entrytype)
- {
- /* end */
- case ADDRMAP_TOKEN_END:
- break;
-
- /* including */
- case ADDRMAP_TOKEN_INCLUDE:
- map_detokenize(memdata, map, driver, devconfig, TOKEN_GET_PTR(tokens, tokenptr));
- for (entryptr = &map->entrylist; *entryptr != NULL; entryptr = &(*entryptr)->next) ;
- entry = NULL;
- break;
-
- /* global flags */
- case ADDRMAP_TOKEN_GLOBAL_MASK:
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, tmap.globalmask, 32);
- check_map(globalmask);
- map->globalmask = tmap.globalmask;
- break;
-
- case ADDRMAP_TOKEN_UNMAP_VALUE:
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, tmap.unmapval, 1);
- check_map(unmapval);
- map->unmapval = tmap.unmapval;
- break;
-
- /* start a new range */
- case ADDRMAP_TOKEN_RANGE:
- entry = *entryptr = global_alloc_clear(address_map_entry);
- entryptr = &entry->next;
- TOKEN_GET_UINT64_UNPACK2(tokens, entry->addrstart, 32, entry->addrend, 32);
- break;
-
- case ADDRMAP_TOKEN_MASK:
- check_entry_field(addrmask);
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, entry->addrmask, 32);
- break;
-
- case ADDRMAP_TOKEN_MIRROR:
- check_entry_field(addrmirror);
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, entry->addrmirror, 32);
- if (entry->addrmirror != 0)
- {
- entry->addrstart &= ~entry->addrmirror;
- entry->addrend &= ~entry->addrmirror;
- }
- break;
-
- case ADDRMAP_TOKEN_READ:
- check_entry_handler(read);
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT32_UNPACK4(tokens, entrytype, 8, maptype, 8, entry->read.bits, 8, entry->read.mask, 8);
- entry->read.type = (map_handler_type)maptype;
- if (entry->read.type == AMH_HANDLER || entry->read.type == AMH_DEVICE_HANDLER)
- {
- entry->read.handler.read = TOKEN_GET_PTR(tokens, read);
- entry->read.name = TOKEN_GET_STRING(tokens);
- }
- if (entry->read.type == AMH_DEVICE_HANDLER || entry->read.type == AMH_PORT || entry->read.type == AMH_BANK)
- entry->read.tag = devconfig->siblingtag(entry->read.derived_tag, TOKEN_GET_STRING(tokens));
- break;
-
- case ADDRMAP_TOKEN_WRITE:
- check_entry_handler(write);
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT32_UNPACK4(tokens, entrytype, 8, maptype, 8, entry->write.bits, 8, entry->write.mask, 8);
- entry->write.type = (map_handler_type)maptype;
- if (entry->write.type == AMH_HANDLER || entry->write.type == AMH_DEVICE_HANDLER)
- {
- entry->write.handler.write = TOKEN_GET_PTR(tokens, write);
- entry->write.name = TOKEN_GET_STRING(tokens);
- }
- if (entry->write.type == AMH_DEVICE_HANDLER || entry->write.type == AMH_PORT || entry->write.type == AMH_BANK)
- entry->write.tag = devconfig->siblingtag(entry->write.derived_tag, TOKEN_GET_STRING(tokens));
- break;
-
- case ADDRMAP_TOKEN_READWRITE:
- check_entry_handler(read);
- check_entry_handler(write);
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT32_UNPACK4(tokens, entrytype, 8, maptype, 8, entry->read.bits, 8, entry->read.mask, 8);
- entry->write.type = entry->read.type = (map_handler_type)maptype;
- entry->write.bits = entry->read.bits;
- entry->write.mask = entry->read.mask;
- if (entry->read.type == AMH_HANDLER || entry->read.type == AMH_DEVICE_HANDLER)
- {
- entry->read.handler.read = TOKEN_GET_PTR(tokens, read);
- entry->read.name = TOKEN_GET_STRING(tokens);
- entry->write.handler.write = TOKEN_GET_PTR(tokens, write);
- entry->write.name = TOKEN_GET_STRING(tokens);
- }
- if (entry->read.type == AMH_DEVICE_HANDLER || entry->read.type == AMH_PORT || entry->read.type == AMH_BANK)
- {
- const char *basetag = TOKEN_GET_STRING(tokens);
- entry->read.tag = devconfig->siblingtag(entry->read.derived_tag, basetag);
- entry->write.tag = devconfig->siblingtag(entry->write.derived_tag, basetag);
- }
- break;
-
- case ADDRMAP_TOKEN_REGION:
- check_entry_field(region);
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, entry->rgnoffs, 32);
- entry->region = devconfig->siblingtag(entry->region_string, TOKEN_GET_STRING(tokens));
- break;
-
- case ADDRMAP_TOKEN_SHARE:
- check_entry_field(share);
- entry->share = TOKEN_GET_STRING(tokens);
- if (memdata != NULL)
- memdata->sharemap.add(entry->share, UNMAPPED_SHARE_PTR, FALSE);
- break;
-
- case ADDRMAP_TOKEN_BASEPTR:
- check_entry_field(baseptr);
- entry->baseptr = (void **)TOKEN_GET_PTR(tokens, voidptr);
- break;
-
- case ADDRMAP_TOKEN_BASE_MEMBER:
- check_entry_field(baseptroffs_plus1);
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, entry->baseptroffs_plus1, 24);
- entry->baseptroffs_plus1++;
- break;
-
- case ADDRMAP_TOKEN_BASE_GENERIC:
- check_entry_field(genbaseptroffs_plus1);
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, entry->genbaseptroffs_plus1, 24);
- entry->genbaseptroffs_plus1++;
- break;
-
- case ADDRMAP_TOKEN_SIZEPTR:
- check_entry_field(sizeptr);
- entry->sizeptr = TOKEN_GET_PTR(tokens, sizeptr);
- break;
-
- case ADDRMAP_TOKEN_SIZE_MEMBER:
- check_entry_field(sizeptroffs_plus1);
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, entry->sizeptroffs_plus1, 24);
- entry->sizeptroffs_plus1++;
- break;
-
- case ADDRMAP_TOKEN_SIZE_GENERIC:
- check_entry_field(gensizeptroffs_plus1);
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, entry->gensizeptroffs_plus1, 24);
- entry->gensizeptroffs_plus1++;
- break;
-
- default:
- fatalerror("Invalid token %d in address map\n", entrytype);
- break;
- }
- }
-
- /* post-process to apply the global mask */
- if (map->globalmask != 0)
- for (entry = map->entrylist; entry != NULL; entry = entry->next)
- {
- entry->addrstart &= map->globalmask;
- entry->addrend &= map->globalmask;
- entry->addrmask &= map->globalmask;
- }
-}
-
-#endif
diff --git a/src/emu/addrmap.h b/src/emu/addrmap.h
index 2a397bd1afa..24cfcde5919 100644
--- a/src/emu/addrmap.h
+++ b/src/emu/addrmap.h
@@ -60,8 +60,10 @@ enum map_handler_type
AMH_ROM,
AMH_NOP,
AMH_UNMAP,
- AMH_HANDLER,
- AMH_DEVICE_HANDLER,
+ AMH_DRIVER_DELEGATE,
+ AMH_DEVICE_DELEGATE,
+ AMH_LEGACY_SPACE_HANDLER,
+ AMH_LEGACY_DEVICE_HANDLER,
AMH_PORT,
AMH_BANK
};
@@ -72,67 +74,25 @@ enum map_handler_type
// TYPE DEFINITIONS
//**************************************************************************
-// address map constructors are functions generated by tokens
-typedef void (*address_map_constructor)(address_map &map, const device_config &devconfig);
-
-
-// read_handler is a union of all the different read handler types
-union read_handler
-{
- genf * generic; // generic function pointer
- read8_space_func shandler8; // 8-bit space read handler
- read16_space_func shandler16; // 16-bit space read handler
- read32_space_func shandler32; // 32-bit space read handler
- read64_space_func shandler64; // 64-bit space read handler
- read8_device_func dhandler8; // 8-bit device read handler
- read16_device_func dhandler16; // 16-bit device read handler
- read32_device_func dhandler32; // 32-bit device read handler
- read64_device_func dhandler64; // 64-bit device read handler
-};
-
-
-// write_handler is a union of all the different write handler types
-union write_handler
-{
- genf * generic; // generic function pointer
- write8_space_func shandler8; // 8-bit space write handler
- write16_space_func shandler16; // 16-bit space write handler
- write32_space_func shandler32; // 32-bit space write handler
- write64_space_func shandler64; // 64-bit space write handler
- write8_device_func dhandler8; // 8-bit device write handler
- write16_device_func dhandler16; // 16-bit device write handler
- write32_device_func dhandler32; // 32-bit device write handler
- write64_device_func dhandler64; // 64-bit device write handler
-};
-
-
-// memory_handler is a union of all read and write handler types
-union memory_handler
-{
- genf * generic; // generic function pointer
- read_handler read; // read handler union
- write_handler write; // write handler union
-};
-
-
// address map handler data
class map_handler_data
{
public:
map_handler_data()
- : type(AMH_NONE),
- bits(0),
- mask(0),
- name(NULL),
- tag(NULL) { handler.generic = NULL; }
-
- map_handler_type type; // type of the handler
- UINT8 bits; // width of the handler in bits, or 0 for default
- UINT8 mask; // mask for which lanes apply
- memory_handler handler; // a memory handler
- const char * name; // name of the handler
- const char * tag; // tag pointing to a reference
- astring derived_tag; // string used to hold derived names
+ : m_type(AMH_NONE),
+ m_bits(0),
+ m_mask(0),
+ m_name(NULL),
+ m_tag(NULL) { }
+
+ map_handler_type m_type; // type of the handler
+ UINT8 m_bits; // width of the handler in bits, or 0 for default
+ UINT64 m_mask; // mask for which lanes apply
+ const char * m_name; // name of the handler
+ const char * m_tag; // tag pointing to a reference
+ astring m_derived_tag; // string used to hold derived names
+
+ void set_tag(const device_config &devconfig, const char *tag);
};
@@ -145,11 +105,14 @@ class address_map_entry
public:
// construction/destruction
address_map_entry(address_map &map, offs_t start, offs_t end);
+
+ // getters
+ address_map_entry *next() const { return m_next; }
// simple inline setters
void set_mirror(offs_t _mirror) { m_addrmirror = _mirror; }
- void set_read_type(map_handler_type _type) { m_read.type = _type; }
- void set_write_type(map_handler_type _type) { m_write.type = _type; }
+ void set_read_type(map_handler_type _type) { m_read.m_type = _type; }
+ void set_write_type(map_handler_type _type) { m_write.m_type = _type; }
void set_region(const char *tag, offs_t offset) { m_region = tag; m_rgnoffs = offset; }
void set_share(const char *tag) { m_share = tag; }
void set_sizeptr(size_t *_sizeptr) { m_sizeptr = _sizeptr; }
@@ -172,31 +135,59 @@ public:
void set_readwrite_bank(const device_config &devconfig, const char *tag);
// public state
- address_map_entry * m_next; // pointer to the next entry
- address_map & m_map; // reference to our owning map
- astring m_region_string; // string used to hold derived names
-
- offs_t m_addrstart; // start address
- offs_t m_addrend; // end address
- offs_t m_addrmirror; // mirror bits
- offs_t m_addrmask; // mask bits
- map_handler_data m_read; // data for read handler
- map_handler_data m_write; // data for write handler
- const char * m_share; // tag of a shared memory block
- void ** m_baseptr; // receives pointer to memory (optional)
- size_t * m_sizeptr; // receives size of area in bytes (optional)
- UINT32 m_baseptroffs_plus1; // offset of base pointer within driver_data, plus 1
- UINT32 m_sizeptroffs_plus1; // offset of size pointer within driver_data, plus 1
- UINT32 m_genbaseptroffs_plus1; // offset of base pointer within generic_pointers, plus 1
- UINT32 m_gensizeptroffs_plus1; // offset of size pointer within generic_pointers, plus 1
- const char * m_region; // tag of region containing the memory backing this entry
- offs_t m_rgnoffs; // offset within the region
-
- void * m_memory; // pointer to memory backing this entry
- offs_t m_bytestart; // byte-adjusted start address
- offs_t m_byteend; // byte-adjusted end address
- offs_t m_bytemirror; // byte-adjusted mirror bits
- offs_t m_bytemask; // byte-adjusted mask bits
+ address_map_entry * m_next; // pointer to the next entry
+ address_map & m_map; // reference to our owning map
+ astring m_region_string; // string used to hold derived names
+
+ // basic information
+ offs_t m_addrstart; // start address
+ offs_t m_addrend; // end address
+ offs_t m_addrmirror; // mirror bits
+ offs_t m_addrmask; // mask bits
+ map_handler_data m_read; // data for read handler
+ map_handler_data m_write; // data for write handler
+ const char * m_share; // tag of a shared memory block
+ void ** m_baseptr; // receives pointer to memory (optional)
+ size_t * m_sizeptr; // receives size of area in bytes (optional)
+ UINT32 m_baseptroffs_plus1; // offset of base pointer within driver_data, plus 1
+ UINT32 m_sizeptroffs_plus1; // offset of size pointer within driver_data, plus 1
+ UINT32 m_genbaseptroffs_plus1; // offset of base pointer within generic_pointers, plus 1
+ UINT32 m_gensizeptroffs_plus1; // offset of size pointer within generic_pointers, plus 1
+ const char * m_region; // tag of region containing the memory backing this entry
+ offs_t m_rgnoffs; // offset within the region
+
+ // handlers
+ read8_proto_delegate m_rproto8; // 8-bit read proto-delegate
+ read16_proto_delegate m_rproto16; // 16-bit read proto-delegate
+ read32_proto_delegate m_rproto32; // 32-bit read proto-delegate
+ read64_proto_delegate m_rproto64; // 64-bit read proto-delegate
+ read8_space_func m_rspace8; // 8-bit legacy address space handler
+ read16_space_func m_rspace16; // 16-bit legacy address space handler
+ read32_space_func m_rspace32; // 32-bit legacy address space handler
+ read64_space_func m_rspace64; // 64-bit legacy address space handler
+ read8_device_func m_rdevice8; // 8-bit legacy device handler
+ read16_device_func m_rdevice16; // 16-bit legacy device handler
+ read32_device_func m_rdevice32; // 32-bit legacy device handler
+ read64_device_func m_rdevice64; // 64-bit legacy device handler
+ write8_proto_delegate m_wproto8; // 8-bit write proto-delegate
+ write16_proto_delegate m_wproto16; // 16-bit write proto-delegate
+ write32_proto_delegate m_wproto32; // 32-bit write proto-delegate
+ write64_proto_delegate m_wproto64; // 64-bit write proto-delegate
+ write8_space_func m_wspace8; // 8-bit legacy address space handler
+ write16_space_func m_wspace16; // 16-bit legacy address space handler
+ write32_space_func m_wspace32; // 32-bit legacy address space handler
+ write64_space_func m_wspace64; // 64-bit legacy address space handler
+ write8_device_func m_wdevice8; // 8-bit legacy device handler
+ write16_device_func m_wdevice16; // 16-bit legacy device handler
+ write32_device_func m_wdevice32; // 32-bit legacy device handler
+ write64_device_func m_wdevice64; // 64-bit legacy device handler
+
+ // information used during processing
+ void * m_memory; // pointer to memory backing this entry
+ offs_t m_bytestart; // byte-adjusted start address
+ offs_t m_byteend; // byte-adjusted end address
+ offs_t m_bytemirror; // byte-adjusted mirror bits
+ offs_t m_bytemask; // byte-adjusted mask bits
protected:
// internal base pointer setting (derived classes provide typed versions)
@@ -205,10 +196,13 @@ protected:
// internal handler setters for 8-bit functions
void internal_set_handler(read8_space_func func, const char *string, UINT64 mask);
void internal_set_handler(write8_space_func func, const char *string, UINT64 mask);
- void internal_set_handler(read8_space_func rfunc, const char *rstring,write8_space_func wfunc, const char *wstring, UINT64 mask);
+ void internal_set_handler(read8_space_func rfunc, const char *rstring, write8_space_func wfunc, const char *wstring, UINT64 mask);
void internal_set_handler(const device_config &devconfig, const char *tag, read8_device_func func, const char *string, UINT64 mask);
void internal_set_handler(const device_config &devconfig, const char *tag, write8_device_func func, const char *string, UINT64 mask);
void internal_set_handler(const device_config &devconfig, const char *tag, read8_device_func rfunc, const char *rstring, write8_device_func wfunc, const char *wstring, UINT64 mask);
+ void internal_set_handler(const device_config &devconfig, const char *tag, read8_proto_delegate func, UINT64 mask);
+ void internal_set_handler(const device_config &devconfig, const char *tag, write8_proto_delegate func, UINT64 mask);
+ void internal_set_handler(const device_config &devconfig, const char *tag, read8_proto_delegate rfunc, write8_proto_delegate wfunc, UINT64 mask);
// internal handler setters for 16-bit functions
void internal_set_handler(read16_space_func func, const char *string, UINT64 mask);
@@ -217,6 +211,9 @@ protected:
void internal_set_handler(const device_config &devconfig, const char *tag, read16_device_func func, const char *string, UINT64 mask);
void internal_set_handler(const device_config &devconfig, const char *tag, write16_device_func func, const char *string, UINT64 mask);
void internal_set_handler(const device_config &devconfig, const char *tag, read16_device_func rfunc, const char *rstring, write16_device_func wfunc, const char *wstring, UINT64 mask);
+ void internal_set_handler(const device_config &devconfig, const char *tag, read16_proto_delegate func, UINT64 mask);
+ void internal_set_handler(const device_config &devconfig, const char *tag, write16_proto_delegate func, UINT64 mask);
+ void internal_set_handler(const device_config &devconfig, const char *tag, read16_proto_delegate rfunc, write16_proto_delegate wfunc, UINT64 mask);
// internal handler setters for 32-bit functions
void internal_set_handler(read32_space_func func, const char *string, UINT64 mask);
@@ -225,6 +222,9 @@ protected:
void internal_set_handler(const device_config &devconfig, const char *tag, read32_device_func func, const char *string, UINT64 mask);
void internal_set_handler(const device_config &devconfig, const char *tag, write32_device_func func, const char *string, UINT64 mask);
void internal_set_handler(const device_config &devconfig, const char *tag, read32_device_func rfunc, const char *rstring, write32_device_func wfunc, const char *wstring, UINT64 mask);
+ void internal_set_handler(const device_config &devconfig, const char *tag, read32_proto_delegate func, UINT64 mask);
+ void internal_set_handler(const device_config &devconfig, const char *tag, write32_proto_delegate func, UINT64 mask);
+ void internal_set_handler(const device_config &devconfig, const char *tag, read32_proto_delegate rfunc, write32_proto_delegate wfunc, UINT64 mask);
// internal handler setters for 64-bit functions
void internal_set_handler(read64_space_func func, const char *string, UINT64 mask);
@@ -233,6 +233,9 @@ protected:
void internal_set_handler(const device_config &devconfig, const char *tag, read64_device_func func, const char *string, UINT64 mask);
void internal_set_handler(const device_config &devconfig, const char *tag, write64_device_func func, const char *string, UINT64 mask);
void internal_set_handler(const device_config &devconfig, const char *tag, read64_device_func rfunc, const char *rstring, write64_device_func wfunc, const char *wstring, UINT64 mask);
+ void internal_set_handler(const device_config &devconfig, const char *tag, read64_proto_delegate func, UINT64 mask);
+ void internal_set_handler(const device_config &devconfig, const char *tag, write64_proto_delegate func, UINT64 mask);
+ void internal_set_handler(const device_config &devconfig, const char *tag, read64_proto_delegate rfunc, write64_proto_delegate wfunc, UINT64 mask);
private:
// helper functions
@@ -257,6 +260,9 @@ public:
void set_handler(const device_config &devconfig, const char *tag, read8_device_func func, const char *string) { internal_set_handler(devconfig, tag, func, string, 0); }
void set_handler(const device_config &devconfig, const char *tag, write8_device_func func, const char *string) { internal_set_handler(devconfig, tag, func, string, 0); }
void set_handler(const device_config &devconfig, const char *tag, read8_device_func rfunc, const char *rstring, write8_device_func wfunc, const char *wstring) { internal_set_handler(devconfig, tag, rfunc, rstring, wfunc, wstring, 0); }
+ void set_handler(const device_config &devconfig, const char *tag, read8_proto_delegate func) { internal_set_handler(devconfig, tag, func, 0); }
+ void set_handler(const device_config &devconfig, const char *tag, write8_proto_delegate func) { internal_set_handler(devconfig, tag, func, 0); }
+ void set_handler(const device_config &devconfig, const char *tag, read8_proto_delegate rfunc, write8_proto_delegate wfunc) { internal_set_handler(devconfig, tag, rfunc, wfunc, 0); }
};
@@ -277,6 +283,9 @@ public:
void set_handler(const device_config &devconfig, const char *tag, read16_device_func func, const char *string) { internal_set_handler(devconfig, tag, func, string, 0); }
void set_handler(const device_config &devconfig, const char *tag, write16_device_func func, const char *string) { internal_set_handler(devconfig, tag, func, string, 0); }
void set_handler(const device_config &devconfig, const char *tag, read16_device_func rfunc, const char *rstring, write16_device_func wfunc, const char *wstring) { internal_set_handler(devconfig, tag, rfunc, rstring, wfunc, wstring, 0); }
+ void set_handler(const device_config &devconfig, const char *tag, read16_proto_delegate func) { internal_set_handler(devconfig, tag, func, 0); }
+ void set_handler(const device_config &devconfig, const char *tag, write16_proto_delegate func) { internal_set_handler(devconfig, tag, func, 0); }
+ void set_handler(const device_config &devconfig, const char *tag, read16_proto_delegate rfunc, write16_proto_delegate wfunc) { internal_set_handler(devconfig, tag, rfunc, wfunc, 0); }
// 8-bit handlers
void set_handler(read8_space_func func, const char *string, UINT16 mask) { internal_set_handler(func, string, mask); }
@@ -285,6 +294,9 @@ public:
void set_handler(const device_config &devconfig, const char *tag, read8_device_func func, const char *string, UINT16 mask) { internal_set_handler(devconfig, tag, func, string, mask); }
void set_handler(const device_config &devconfig, const char *tag, write8_device_func func, const char *string, UINT16 mask) { internal_set_handler(devconfig, tag, func, string, mask); }
void set_handler(const device_config &devconfig, const char *tag, read8_device_func rfunc, const char *rstring, write8_device_func wfunc, const char *wstring, UINT16 mask) { internal_set_handler(devconfig, tag, rfunc, rstring, wfunc, wstring, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, read8_proto_delegate func, UINT16 mask) { internal_set_handler(devconfig, tag, func, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, write8_proto_delegate func, UINT16 mask) { internal_set_handler(devconfig, tag, func, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, read8_proto_delegate rfunc, write8_proto_delegate wfunc, UINT16 mask) { internal_set_handler(devconfig, tag, rfunc, wfunc, mask); }
};
@@ -305,6 +317,9 @@ public:
void set_handler(const device_config &devconfig, const char *tag, read32_device_func func, const char *string) { internal_set_handler(devconfig, tag, func, string, 0); }
void set_handler(const device_config &devconfig, const char *tag, write32_device_func func, const char *string) { internal_set_handler(devconfig, tag, func, string, 0); }
void set_handler(const device_config &devconfig, const char *tag, read32_device_func rfunc, const char *rstring, write32_device_func wfunc, const char *wstring) { internal_set_handler(devconfig, tag, rfunc, rstring, wfunc, wstring, 0); }
+ void set_handler(const device_config &devconfig, const char *tag, read32_proto_delegate func) { internal_set_handler(devconfig, tag, func, 0); }
+ void set_handler(const device_config &devconfig, const char *tag, write32_proto_delegate func) { internal_set_handler(devconfig, tag, func, 0); }
+ void set_handler(const device_config &devconfig, const char *tag, read32_proto_delegate rfunc, write32_proto_delegate wfunc) { internal_set_handler(devconfig, tag, rfunc, wfunc, 0); }
// 16-bit handlers
void set_handler(read16_space_func func, const char *string, UINT32 mask) { internal_set_handler(func, string, mask); }
@@ -313,6 +328,9 @@ public:
void set_handler(const device_config &devconfig, const char *tag, read16_device_func func, const char *string, UINT32 mask) { internal_set_handler(devconfig, tag, func, string, mask); }
void set_handler(const device_config &devconfig, const char *tag, write16_device_func func, const char *string, UINT32 mask) { internal_set_handler(devconfig, tag, func, string, mask); }
void set_handler(const device_config &devconfig, const char *tag, read16_device_func rfunc, const char *rstring, write16_device_func wfunc, const char *wstring, UINT32 mask) { internal_set_handler(devconfig, tag, rfunc, rstring, wfunc, wstring, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, read16_proto_delegate func, UINT32 mask) { internal_set_handler(devconfig, tag, func, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, write16_proto_delegate func, UINT32 mask) { internal_set_handler(devconfig, tag, func, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, read16_proto_delegate rfunc, write16_proto_delegate wfunc, UINT32 mask) { internal_set_handler(devconfig, tag, rfunc, wfunc, mask); }
// 8-bit handlers
void set_handler(read8_space_func func, const char *string, UINT32 mask) { internal_set_handler(func, string, mask); }
@@ -321,6 +339,9 @@ public:
void set_handler(const device_config &devconfig, const char *tag, read8_device_func func, const char *string, UINT32 mask) { internal_set_handler(devconfig, tag, func, string, mask); }
void set_handler(const device_config &devconfig, const char *tag, write8_device_func func, const char *string, UINT32 mask) { internal_set_handler(devconfig, tag, func, string, mask); }
void set_handler(const device_config &devconfig, const char *tag, read8_device_func rfunc, const char *rstring, write8_device_func wfunc, const char *wstring, UINT32 mask) { internal_set_handler(devconfig, tag, rfunc, rstring, wfunc, wstring, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, read8_proto_delegate func, UINT32 mask) { internal_set_handler(devconfig, tag, func, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, write8_proto_delegate func, UINT32 mask) { internal_set_handler(devconfig, tag, func, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, read8_proto_delegate rfunc, write8_proto_delegate wfunc, UINT32 mask) { internal_set_handler(devconfig, tag, rfunc, wfunc, mask); }
};
@@ -341,6 +362,9 @@ public:
void set_handler(const device_config &devconfig, const char *tag, read64_device_func func, const char *string) { internal_set_handler(devconfig, tag, func, string, 0); }
void set_handler(const device_config &devconfig, const char *tag, write64_device_func func, const char *string) { internal_set_handler(devconfig, tag, func, string, 0); }
void set_handler(const device_config &devconfig, const char *tag, read64_device_func rfunc, const char *rstring, write64_device_func wfunc, const char *wstring) { internal_set_handler(devconfig, tag, rfunc, rstring, wfunc, wstring, 0); }
+ void set_handler(const device_config &devconfig, const char *tag, read64_proto_delegate func) { internal_set_handler(devconfig, tag, func, 0); }
+ void set_handler(const device_config &devconfig, const char *tag, write64_proto_delegate func) { internal_set_handler(devconfig, tag, func, 0); }
+ void set_handler(const device_config &devconfig, const char *tag, read64_proto_delegate rfunc, write64_proto_delegate wfunc) { internal_set_handler(devconfig, tag, rfunc, wfunc, 0); }
// 32-bit handlers
void set_handler(read32_space_func func, const char *string, UINT64 mask) { internal_set_handler(func, string, mask); }
@@ -349,6 +373,9 @@ public:
void set_handler(const device_config &devconfig, const char *tag, read32_device_func func, const char *string, UINT64 mask) { internal_set_handler(devconfig, tag, func, string, mask); }
void set_handler(const device_config &devconfig, const char *tag, write32_device_func func, const char *string, UINT64 mask) { internal_set_handler(devconfig, tag, func, string, mask); }
void set_handler(const device_config &devconfig, const char *tag, read32_device_func rfunc, const char *rstring, write32_device_func wfunc, const char *wstring, UINT64 mask) { internal_set_handler(devconfig, tag, rfunc, rstring, wfunc, wstring, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, read32_proto_delegate func, UINT64 mask) { internal_set_handler(devconfig, tag, func, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, write32_proto_delegate func, UINT64 mask) { internal_set_handler(devconfig, tag, func, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, read32_proto_delegate rfunc, write32_proto_delegate wfunc, UINT64 mask) { internal_set_handler(devconfig, tag, rfunc, wfunc, mask); }
// 16-bit handlers
void set_handler(read16_space_func func, const char *string, UINT64 mask) { internal_set_handler(func, string, mask); }
@@ -357,6 +384,9 @@ public:
void set_handler(const device_config &devconfig, const char *tag, read16_device_func func, const char *string, UINT64 mask) { internal_set_handler(devconfig, tag, func, string, mask); }
void set_handler(const device_config &devconfig, const char *tag, write16_device_func func, const char *string, UINT64 mask) { internal_set_handler(devconfig, tag, func, string, mask); }
void set_handler(const device_config &devconfig, const char *tag, read16_device_func rfunc, const char *rstring, write16_device_func wfunc, const char *wstring, UINT64 mask) { internal_set_handler(devconfig, tag, rfunc, rstring, wfunc, wstring, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, read16_proto_delegate func, UINT64 mask) { internal_set_handler(devconfig, tag, func, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, write16_proto_delegate func, UINT64 mask) { internal_set_handler(devconfig, tag, func, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, read16_proto_delegate rfunc, write16_proto_delegate wfunc, UINT64 mask) { internal_set_handler(devconfig, tag, rfunc, wfunc, mask); }
// 8-bit handlers
void set_handler(read8_space_func func, const char *string, UINT64 mask) { internal_set_handler(func, string, mask); }
@@ -365,6 +395,9 @@ public:
void set_handler(const device_config &devconfig, const char *tag, read8_device_func func, const char *string, UINT64 mask) { internal_set_handler(devconfig, tag, func, string, mask); }
void set_handler(const device_config &devconfig, const char *tag, write8_device_func func, const char *string, UINT64 mask) { internal_set_handler(devconfig, tag, func, string, mask); }
void set_handler(const device_config &devconfig, const char *tag, read8_device_func rfunc, const char *rstring, write8_device_func wfunc, const char *wstring, UINT64 mask) { internal_set_handler(devconfig, tag, rfunc, rstring, wfunc, wstring, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, read8_proto_delegate func, UINT64 mask) { internal_set_handler(devconfig, tag, func, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, write8_proto_delegate func, UINT64 mask) { internal_set_handler(devconfig, tag, func, mask); }
+ void set_handler(const device_config &devconfig, const char *tag, read8_proto_delegate rfunc, write8_proto_delegate wfunc, UINT64 mask) { internal_set_handler(devconfig, tag, rfunc, wfunc, mask); }
};
@@ -396,11 +429,7 @@ public:
UINT8 m_databits; // data bits represented by the map
UINT8 m_unmapval; // unmapped memory value
offs_t m_globalmask; // global mask
- address_map_entry * m_entrylist; // list of entries
-
-private:
- // internal data
- address_map_entry ** m_tailptr;
+ simple_list<address_map_entry> m_entrylist; // list of entries
};
@@ -419,6 +448,8 @@ private:
#define ADDRESS_MAP_START(_name, _space, _bits) \
void ADDRESS_MAP_NAME(_name)(address_map &map, const device_config &devconfig) \
{ \
+ typedef read##_bits##_proto_delegate read_proto_delegate; \
+ typedef write##_bits##_proto_delegate write_proto_delegate; \
address_map_entry##_bits *curentry = NULL; \
(void)curentry; \
map.configure(_space, _bits); \
@@ -458,7 +489,7 @@ void ADDRESS_MAP_NAME(_name)(address_map &map, const device_config &devconfig) \
curentry->set_mirror(_mirror); \
-// space reads
+// legacy space reads
#define AM_READ(_handler) \
curentry->set_handler(_handler, #_handler); \
@@ -472,7 +503,7 @@ void ADDRESS_MAP_NAME(_name)(address_map &map, const device_config &devconfig) \
curentry->set_handler(_handler, #_handler, _unitmask); \
-// space writes
+// legacy space writes
#define AM_WRITE(_handler) \
curentry->set_handler(_handler, #_handler); \
@@ -486,7 +517,7 @@ void ADDRESS_MAP_NAME(_name)(address_map &map, const device_config &devconfig) \
curentry->set_handler(_handler, #_handler, _unitmask); \
-// space reads/writes
+// legacy space reads/writes
#define AM_READWRITE(_rhandler, _whandler) \
curentry->set_handler(_rhandler, #_rhandler, _whandler, #_whandler); \
@@ -500,7 +531,7 @@ void ADDRESS_MAP_NAME(_name)(address_map &map, const device_config &devconfig) \
curentry->set_handler(_rhandler, #_rhandler, _whandler, #_whandler, _unitmask); \
-// device reads
+// legacy device reads
#define AM_DEVREAD(_tag, _handler) \
curentry->set_handler(devconfig, _tag, _handler, #_handler); \
@@ -514,7 +545,7 @@ void ADDRESS_MAP_NAME(_name)(address_map &map, const device_config &devconfig) \
curentry->set_handler(devconfig, _tag, _handler, #_handler, _unitmask); \
-// device writes
+// legacy device writes
#define AM_DEVWRITE(_tag, _handler) \
curentry->set_handler(devconfig, _tag, _handler, #_handler); \
@@ -528,7 +559,7 @@ void ADDRESS_MAP_NAME(_name)(address_map &map, const device_config &devconfig) \
curentry->set_handler(devconfig, _tag, _handler, #_handler, _unitmask); \
-// device reads/writes
+// legacy device reads/writes
#define AM_DEVREADWRITE(_tag, _rhandler, _whandler) \
curentry->set_handler(devconfig, _tag, _rhandler, #_rhandler, _whandler, #_whandler); \
@@ -542,6 +573,90 @@ void ADDRESS_MAP_NAME(_name)(address_map &map, const device_config &devconfig) \
curentry->set_handler(devconfig, _tag, _rhandler, #_rhandler, _whandler, #_whandler, _unitmask); \
+// driver data reads
+#define AM_READ_MEMBER(_class, _handler) \
+ curentry->set_handler(devconfig, NULL, read_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler)); \
+
+#define AM_READ8_MEMBER(_class, _handler, _unitmask) \
+ curentry->set_handler(devconfig, NULL, read8_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler), _unitmask); \
+
+#define AM_READ16_MEMBER(_class, _handler, _unitmask) \
+ curentry->set_handler(devconfig, NULL, read16_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler), _unitmask); \
+
+#define AM_READ32_MEMBER(_class, _handler, _unitmask) \
+ curentry->set_handler(devconfig, NULL, read32_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler), _unitmask); \
+
+
+// driver data writes
+#define AM_WRITE_MEMBER(_class, _handler) \
+ curentry->set_handler(devconfig, NULL, write_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler)); \
+
+#define AM_WRITE8_MEMBER(_class, _handler, _unitmask) \
+ curentry->set_handler(devconfig, NULL, write8_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler), _unitmask); \
+
+#define AM_WRITE16_MEMBER(_class, _handler, _unitmask) \
+ curentry->set_handler(devconfig, NULL, write16_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler), _unitmask); \
+
+#define AM_WRITE32_MEMBER(_class, _handler, _unitmask) \
+ curentry->set_handler(devconfig, NULL, write32_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler), _unitmask); \
+
+
+// driver data reads/writes
+#define AM_READWRITE_MEMBER(_class, _rhandler, _whandler) \
+ curentry->set_handler(devconfig, NULL, read_proto_delegate::_create_member<_class, &_class::_rhandler>(#_class "::" #_rhandler), write_proto_delegate::_create_member<_class, &_class::_whandler>(#_class "::" #_whandler)); \
+
+#define AM_READWRITE8_MEMBER(_class, _rhandler, _whandler, _unitmask) \
+ curentry->set_handler(devconfig, NULL, read8_proto_delegate::_create_member<_class, &_class::_rhandler>(#_class "::" #_rhandler), write8_proto_delegate::_create_member<_class, &_class::_whandler>(#_class "::" #_whandler), _unitmask); \
+
+#define AM_READWRITE16_MEMBER(_class, _rhandler, _whandler, _unitmask) \
+ curentry->set_handler(devconfig, NULL, read16_proto_delegate::_create_member<_class, &_class::_rhandler>(#_class "::" #_rhandler), write16_proto_delegate::_create_member<_class, &_class::_whandler>(#_class "::" #_whandler), _unitmask); \
+
+#define AM_READWRITE32_MEMBER(_class, _rhandler, _whandler, _unitmask) \
+ curentry->set_handler(devconfig, NULL, read32_proto_delegate::_create_member<_class, &_class::_rhandler>(#_class "::" #_rhandler), write32_proto_delegate::_create_member<_class, &_class::_whandler>(#_class "::" #_whandler), _unitmask); \
+
+
+// device reads
+#define AM_DEVREAD_MEMBER(_tag, _class, _handler) \
+ curentry->set_handler(devconfig, _tag, read_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler)); \
+
+#define AM_DEVREAD8_MEMBER(_tag, _class, _handler, _unitmask) \
+ curentry->set_handler(devconfig, _tag, read8_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler), _unitmask); \
+
+#define AM_DEVREAD16_MEMBER(_tag, _class, _handler, _unitmask) \
+ curentry->set_handler(devconfig, _tag, read16_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler), _unitmask); \
+
+#define AM_DEVREAD32_MEMBER(_tag, _class, _handler, _unitmask) \
+ curentry->set_handler(devconfig, _tag, read32_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler), _unitmask); \
+
+
+// device writes
+#define AM_DEVWRITE_MEMBER(_tag, _class, _handler) \
+ curentry->set_handler(devconfig, _tag, write_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler)); \
+
+#define AM_DEVWRITE8_MEMBER(_tag, _class, _handler, _unitmask) \
+ curentry->set_handler(devconfig, _tag, write8_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler), _unitmask); \
+
+#define AM_DEVWRITE16_MEMBER(_tag, _class, _handler, _unitmask) \
+ curentry->set_handler(devconfig, _tag, write16_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler), _unitmask); \
+
+#define AM_DEVWRITE32_MEMBER(_tag, _class, _handler, _unitmask) \
+ curentry->set_handler(devconfig, _tag, write32_proto_delegate::_create_member<_class, &_class::_handler>(#_class "::" #_handler), _unitmask); \
+
+
+// device reads/writes
+#define AM_DEVREADWRITE_MEMBER(_tag, _class, _rhandler, _whandler) \
+ curentry->set_handler(devconfig, _tag, read_proto_delegate::_create_member<_class, &_class::_rhandler>(#_class "::" #_rhandler), write_proto_delegate::_create_member<_class, &_class::_whandler>(#_class "::" #_whandler)); \
+
+#define AM_DEVREADWRITE8_MEMBER(_tag, _class, _rhandler, _whandler, _unitmask) \
+ curentry->set_handler(devconfig, _tag, read8_proto_delegate::_create_member<_class, &_class::_rhandler>(#_class "::" #_rhandler), write8_proto_delegate::_create_member<_class, &_class::_whandler>(#_class "::" #_whandler), _unitmask); \
+
+#define AM_DEVREADWRITE16_MEMBER(_tag, _class, _rhandler, _whandler, _unitmask) \
+ curentry->set_handler(devconfig, _tag, read16_proto_delegate::_create_member<_class, &_class::_rhandler>(#_class "::" #_rhandler), write16_proto_delegate::_create_member<_class, &_class::_whandler>(#_class "::" #_whandler), _unitmask); \
+
+#define AM_DEVREADWRITE32_MEMBER(_tag, _class, _rhandler, _whandler, _unitmask) \
+ curentry->set_handler(devconfig, _tag, read32_proto_delegate::_create_member<_class, &_class::_rhandler>(#_class "::" #_rhandler), write32_proto_delegate::_create_member<_class, &_class::_whandler>(#_class "::" #_whandler), _unitmask); \
+
+
// special-case accesses
#define AM_ROM \
curentry->set_read_type(AMH_ROM); \
@@ -624,12 +739,25 @@ void ADDRESS_MAP_NAME(_name)(address_map &map, const device_config &devconfig) \
#define AM_ROMBANK(_bank) AM_READ_BANK(_bank)
#define AM_RAMBANK(_bank) AM_READWRITE_BANK(_bank)
#define AM_RAM_READ(_read) AM_READ(_read) AM_WRITEONLY
+#define AM_RAM_READ_MEMBER(_class, _read) AM_READ_MEMBER(_class, _read) AM_WRITEONLY
#define AM_RAM_WRITE(_write) AM_READONLY AM_WRITE(_write)
-#define AM_RAM_DEVREAD(_tag, _read) AM_DEVREAD(_tag, _read) AM_WRITEONLY
-#define AM_RAM_DEVWRITE(_tag, _write) AM_READONLY AM_DEVWRITE(_tag, _write)
+#define AM_RAM_WRITE_MEMBER(_class, _write) AM_READONLY AM_WRITE_MEMBER(_class, _write)
+#define AM_RAM_DEVREAD(_tag, _read) AM_DEVREAD(_tag, _read) AM_WRITEONLY
+#define AM_RAM_DEVREAD_MEMBER(_tag, _class, _read) AM_DEVREAD_MEMBER(_tag, _class, _read) AM_WRITEONLY
+#define AM_RAM_DEVWRITE(_tag, _write) AM_READONLY AM_DEVWRITE(_tag, _write)
+#define AM_RAM_DEVWRITE_MEMBER(_tag, _class, _write) AM_READONLY AM_DEVWRITE_MEMBER(_tag, _class, _write)
#define AM_BASE_SIZE_MEMBER(_struct, _base, _size) AM_BASE_MEMBER(_struct, _base) AM_SIZE_MEMBER(_struct, _size)
#define AM_BASE_SIZE_GENERIC(_member) AM_BASE_GENERIC(_member) AM_SIZE_GENERIC(_member)
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+// use this to refer to the owning device when providing a device tag
+static const char DEVICE_SELF[] = "";
+
+
#endif /* __ADDRMAP_H__ */
diff --git a/src/emu/cpu/drcbex64.c b/src/emu/cpu/drcbex64.c
index a17b145dc7d..c9da5eae42c 100644
--- a/src/emu/cpu/drcbex64.c
+++ b/src/emu/cpu/drcbex64.c
@@ -277,7 +277,7 @@ struct _drcbe_state
x86code * debug_cpu_instruction_hook;/* debugger callback */
x86code * debug_log_hashjmp; /* hashjmp debugging */
x86code * drcmap_get_value; /* map lookup helper */
- data_accessors accessors[ADDRESS_SPACES];/* memory accessors */
+ data_accessors accessors[ADDRESS_SPACES]; /* memory accessors */
const address_space * space[ADDRESS_SPACES]; /* address spaces */
UINT8 sse41; /* do we have SSE4.1 support? */
@@ -388,7 +388,6 @@ static const UINT8 fprnd_map[4] =
};
-
/***************************************************************************
TABLES
***************************************************************************/
@@ -716,7 +715,7 @@ static drcbe_state *drcbex64_alloc(drcuml_state *drcuml, drccache *cache, runnin
{
drcbe->space[spacenum] = downcast<cpu_device *>(device)->space(spacenum);
if (drcbe->space[spacenum] != NULL)
- drcbe->accessors[spacenum] = drcbe->space[spacenum]->accessors;
+ drcbe->space[spacenum]->accessors(drcbe->accessors[spacenum]);
}
/* build up necessary arrays */
diff --git a/src/emu/cpu/drcbex86.c b/src/emu/cpu/drcbex86.c
index 3580983d59a..b984d75a120 100644
--- a/src/emu/cpu/drcbex86.c
+++ b/src/emu/cpu/drcbex86.c
@@ -178,6 +178,7 @@ struct _drcbe_state
UINT32 * last_upper_addr; /* address where we last stored an upper register */
double fptemp; /* temporary storage for floating point */
+ data_accessors accessors[ADDRESS_SPACES]; /* memory accessors */
const address_space * space[ADDRESS_SPACES]; /* address spaces */
UINT8 sse3; /* do we have SSE3 support? */
@@ -629,9 +630,13 @@ static drcbe_state *drcbex86_alloc(drcuml_state *drcuml, drccache *cache, runnin
drcbe->drcuml = drcuml;
drcbe->cache = cache;
- /* get address spaces */
+ /* get address spaces and accessors */
for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
+ {
drcbe->space[spacenum] = downcast<cpu_device *>(device)->space(spacenum);
+ if (drcbe->space[spacenum] != NULL)
+ drcbe->space[spacenum]->accessors(drcbe->accessors[spacenum]);
+ }
/* allocate hash tables */
drcbe->hash = drchash_alloc(cache, modes, addrbits, ignorebits);
@@ -4262,25 +4267,25 @@ static x86code *op_read(drcbe_state *drcbe, x86code *dst, const drcuml_instructi
emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (UINT32)drcbe->space[spacesizep.value / 16]);// mov [esp],space
if ((spacesizep.value & 3) == DRCUML_SIZE_BYTE)
{
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.read_byte);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_byte);
// call read_byte
emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al
}
else if ((spacesizep.value & 3) == DRCUML_SIZE_WORD)
{
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.read_word);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_word);
// call read_word
emit_movzx_r32_r16(&dst, dstreg, REG_AX); // movzx dstreg,ax
}
else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD)
{
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.read_dword);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_dword);
// call read_dword
emit_mov_r32_r32(&dst, dstreg, REG_EAX); // mov dstreg,eax
}
else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD)
{
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.read_qword);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_qword);
// call read_qword
emit_mov_r32_r32(&dst, dstreg, REG_EAX); // mov dstreg,eax
}
@@ -4342,19 +4347,19 @@ static x86code *op_readm(drcbe_state *drcbe, x86code *dst, const drcuml_instruct
emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (UINT32)drcbe->space[spacesizep.value / 16]);// mov [esp],space
if ((spacesizep.value & 3) == DRCUML_SIZE_WORD)
{
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.read_word_masked);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_word_masked);
// call read_word_masked
emit_movzx_r32_r16(&dst, dstreg, REG_AX); // movzx dstreg,ax
}
else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD)
{
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.read_dword_masked);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_dword_masked);
// call read_dword_masked
emit_mov_r32_r32(&dst, dstreg, REG_EAX); // mov dstreg,eax
}
else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD)
{
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.read_qword_masked);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_qword_masked);
// call read_qword_masked
emit_mov_r32_r32(&dst, dstreg, REG_EAX); // mov dstreg,eax
}
@@ -4411,16 +4416,16 @@ static x86code *op_write(drcbe_state *drcbe, x86code *dst, const drcuml_instruct
emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 4), &addrp); // mov [esp+4],addrp
emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (UINT32)drcbe->space[spacesizep.value / 16]);// mov [esp],space
if ((spacesizep.value & 3) == DRCUML_SIZE_BYTE)
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.write_byte);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_byte);
// call write_byte
else if ((spacesizep.value & 3) == DRCUML_SIZE_WORD)
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.write_word);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_word);
// call write_word
else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD)
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.write_dword);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_dword);
// call write_dword
else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD)
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.write_qword);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_qword);
// call write_qword
return dst;
}
@@ -4456,13 +4461,13 @@ static x86code *op_writem(drcbe_state *drcbe, x86code *dst, const drcuml_instruc
emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 4), &addrp); // mov [esp+4],addrp
emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (UINT32)drcbe->space[spacesizep.value / 16]);// mov [esp],space
if ((spacesizep.value & 3) == DRCUML_SIZE_WORD)
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.write_word_masked);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_word_masked);
// call write_word_masked
else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD)
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.write_dword_masked);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_dword_masked);
// call write_dword_masked
else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD)
- emit_call(&dst, (x86code *)drcbe->space[spacesizep.value / 16]->accessors.write_qword_masked);
+ emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_qword_masked);
// call write_qword_masked
return dst;
}
@@ -6411,9 +6416,9 @@ static x86code *op_fread(drcbe_state *drcbe, x86code *dst, const drcuml_instruct
emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 4), &addrp); // mov [esp+4],addrp
emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (UINT32)drcbe->space[spacep.value]); // mov [esp],space
if (inst->size == 4)
- emit_call(&dst, (x86code *)drcbe->space[spacep.value]->accessors.read_dword); // call read_dword
+ emit_call(&dst, (x86code *)drcbe->accessors[spacep.value].read_dword); // call read_dword
else if (inst->size == 8)
- emit_call(&dst, (x86code *)drcbe->space[spacep.value]->accessors.read_qword); // call read_qword
+ emit_call(&dst, (x86code *)drcbe->accessors[spacep.value].read_qword); // call read_qword
/* store result */
if (inst->size == 4)
@@ -6449,9 +6454,9 @@ static x86code *op_fwrite(drcbe_state *drcbe, x86code *dst, const drcuml_instruc
emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 4), &addrp); // mov [esp+4],addrp
emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (UINT32)drcbe->space[spacep.value]); // mov [esp],space
if (inst->size == 4)
- emit_call(&dst, (x86code *)drcbe->space[spacep.value]->accessors.write_dword); // call write_dword
+ emit_call(&dst, (x86code *)drcbe->accessors[spacep.value].write_dword); // call write_dword
else if (inst->size == 8)
- emit_call(&dst, (x86code *)drcbe->space[spacep.value]->accessors.write_qword); // call write_qword
+ emit_call(&dst, (x86code *)drcbe->accessors[spacep.value].write_qword); // call write_qword
return dst;
}
diff --git a/src/emu/cpu/dsp56k/dsp56k.c b/src/emu/cpu/dsp56k/dsp56k.c
index 4b362ca6bdd..5b3a8e0ae80 100644
--- a/src/emu/cpu/dsp56k/dsp56k.c
+++ b/src/emu/cpu/dsp56k/dsp56k.c
@@ -67,12 +67,12 @@ static CPU_RESET( dsp56k );
/***************************************************************************
Direct Update Handler
***************************************************************************/
-static DIRECT_UPDATE_HANDLER( dsp56k_direct_handler )
+DIRECT_UPDATE_HANDLER( dsp56k_direct_handler )
{
if (address >= (0x0000<<1) && address <= (0x07ff<<1))
{
- dsp56k_core* cpustate = get_safe_token(space->cpu);
- direct->raw = direct->decrypted = (UINT8 *)(cpustate->program_ram - (0x0000<<1));
+ dsp56k_core* cpustate = get_safe_token(direct.space().cpu);
+ direct.explicit_configure(0x0000<<1, 0x07ff<<1, 0x07ff<<1, cpustate->program_ram);
return ~0;
}
@@ -237,7 +237,7 @@ static CPU_INIT( dsp56k )
/* Setup the direct memory handler for this CPU */
/* NOTE: Be sure to grab this guy and call him if you ever install another direct_update_hander in a driver! */
- memory_set_direct_update_handler(cpustate->program, dsp56k_direct_handler);
+ const_cast<address_space *>(cpustate->program)->set_direct_update_handler(direct_update_delegate_create_static(dsp56k_direct_handler, *device->machine));
}
diff --git a/src/emu/cpu/mips/mips3com.c b/src/emu/cpu/mips/mips3com.c
index c54f5a6dbfb..bb4e8cd2ec9 100644
--- a/src/emu/cpu/mips/mips3com.c
+++ b/src/emu/cpu/mips/mips3com.c
@@ -98,7 +98,7 @@ void mips3com_init(mips3_state *mips, mips3_flavor flavor, int bigendian, legacy
}
/* set up the endianness */
- mips->memory = mips->program->accessors;
+ mips->program->accessors(mips->memory);
/* allocate the virtual TLB */
mips->vtlb = vtlb_alloc(device, ADDRESS_SPACE_PROGRAM, 2 * mips->tlbentries + 2, 0);
diff --git a/src/emu/cpu/mips/r3000.c b/src/emu/cpu/mips/r3000.c
index 3a7a94d858f..3f15bb8ed77 100644
--- a/src/emu/cpu/mips/r3000.c
+++ b/src/emu/cpu/mips/r3000.c
@@ -150,7 +150,7 @@ struct _r3000_state
/* memory accesses */
UINT8 bigendian;
data_accessors cur;
- const data_accessors *memory_hand;
+ data_accessors memory_hand;
const data_accessors *cache_hand;
/* cache memory */
@@ -319,9 +319,9 @@ static void r3000_reset(r3000_state *r3000, int bigendian)
{
/* set up the endianness */
r3000->bigendian = bigendian;
+ r3000->program->accessors(r3000->memory_hand);
if (r3000->bigendian)
{
- r3000->memory_hand = &r3000->program->accessors;
r3000->cache_hand = &be_cache;
r3000->lwl = lwl_be;
r3000->lwr = lwr_be;
@@ -330,7 +330,6 @@ static void r3000_reset(r3000_state *r3000, int bigendian)
}
else
{
- r3000->memory_hand = &r3000->program->accessors;
r3000->cache_hand = &le_cache;
r3000->lwl = lwl_le;
r3000->lwr = lwr_le;
@@ -339,7 +338,7 @@ static void r3000_reset(r3000_state *r3000, int bigendian)
}
/* initialize the rest of the config */
- r3000->cur = *r3000->memory_hand;
+ r3000->cur = r3000->memory_hand;
r3000->cache = r3000->dcache;
r3000->cache_size = r3000->dcache_size;
@@ -396,7 +395,7 @@ INLINE void set_cop0_reg(r3000_state *r3000, int idx, UINT32 val)
if (val & SR_IsC)
r3000->cur = *r3000->cache_hand;
else
- r3000->cur = *r3000->memory_hand;
+ r3000->cur = r3000->memory_hand;
}
/* handle cache switching */
diff --git a/src/emu/debug/debugcmd.c b/src/emu/debug/debugcmd.c
index f93d40b5d82..c639226240d 100644
--- a/src/emu/debug/debugcmd.c
+++ b/src/emu/debug/debugcmd.c
@@ -1438,14 +1438,14 @@ static void execute_wplist(running_machine *machine, int ref, int params, const
{
static const char *const types[] = { "unkn ", "read ", "write", "r/w " };
- debug_console_printf(machine, "Device '%s' %s space watchpoints:\n", device->tag(), device->debug()->watchpoint_first(spacenum)->space().name);
+ debug_console_printf(machine, "Device '%s' %s space watchpoints:\n", device->tag(), device->debug()->watchpoint_first(spacenum)->space().name());
/* loop over the watchpoints */
for (device_debug::watchpoint *wp = device->debug()->watchpoint_first(spacenum); wp != NULL; wp = wp->next())
{
buffer.printf("%c%4X @ %s-%s %s", wp->enabled() ? ' ' : 'D', wp->index(),
- core_i64_hex_format(memory_byte_to_address(&wp->space(), wp->address()), wp->space().addrchars),
- core_i64_hex_format(memory_byte_to_address_end(&wp->space(), wp->address() + wp->length()) - 1, wp->space().addrchars),
+ core_i64_hex_format(wp->space().byte_to_address(wp->address()), wp->space().addrchars()),
+ core_i64_hex_format(wp->space().byte_to_address_end(wp->address() + wp->length()) - 1, wp->space().addrchars()),
types[wp->type() & 3]);
if (wp->condition() != NULL)
buffer.catprintf(" if %s", wp->condition());
@@ -1524,8 +1524,8 @@ static void execute_save(running_machine *machine, int ref, int params, const ch
return;
/* determine the addresses to write */
- endoffset = memory_address_to_byte(space, offset + length - 1) & space->bytemask;
- offset = memory_address_to_byte(space, offset) & space->bytemask;
+ endoffset = space->address_to_byte(offset + length - 1) & space->bytemask();
+ offset = space->address_to_byte(offset) & space->bytemask();
/* open the file */
f = fopen(param[0], "wb");
@@ -1573,16 +1573,16 @@ static void execute_dump(running_machine *machine, int ref, int params, const ch
/* further validation */
if (width == 0)
- width = space->dbits / 8;
- if (width < memory_address_to_byte(space, 1))
- width = memory_address_to_byte(space, 1);
+ width = space->data_width() / 8;
+ if (width < space->address_to_byte(1))
+ width = space->address_to_byte(1);
if (width != 1 && width != 2 && width != 4 && width != 8)
{
debug_console_printf(machine, "Invalid width! (must be 1,2,4 or 8)\n");
return;
}
- endoffset = memory_address_to_byte(space, offset + length - 1) & space->bytemask;
- offset = memory_address_to_byte(space, offset) & space->bytemask;
+ endoffset = space->address_to_byte(offset + length - 1) & space->bytemask();
+ offset = space->address_to_byte(offset) & space->bytemask();
/* open the file */
f = fopen(param[0], "w");
@@ -1599,7 +1599,7 @@ static void execute_dump(running_machine *machine, int ref, int params, const ch
int outdex = 0;
/* print the address */
- outdex += sprintf(&output[outdex], "%s: ", core_i64_hex_format((UINT32)memory_byte_to_address(space, i), space->logaddrchars));
+ outdex += sprintf(&output[outdex], "%s: ", core_i64_hex_format((UINT32)space->byte_to_address(i), space->logaddrchars()));
/* print the bytes */
for (j = 0; j < 16; j += width)
@@ -1711,19 +1711,19 @@ static void execute_cheatinit(running_machine *machine, int ref, int params, con
if (params <= 1)
{
offset = 0;
- length = space->bytemask + 1;
- for (entry = space->map->m_entrylist; entry != NULL; entry = entry->m_next)
+ length = space->bytemask() + 1;
+ for (entry = space->map()->m_entrylist.first(); entry != NULL; entry = entry->next())
{
- cheat_region[region_count].offset = memory_address_to_byte(space, entry->m_addrstart) & space->bytemask;
- cheat_region[region_count].endoffset = memory_address_to_byte(space, entry->m_addrend) & space->bytemask;
+ cheat_region[region_count].offset = space->address_to_byte(entry->m_addrstart) & space->bytemask();
+ cheat_region[region_count].endoffset = space->address_to_byte(entry->m_addrend) & space->bytemask();
cheat_region[region_count].share = entry->m_share;
- cheat_region[region_count].disabled = (entry->m_write.type == AMH_RAM) ? FALSE : TRUE;
+ cheat_region[region_count].disabled = (entry->m_write.m_type == AMH_RAM) ? FALSE : TRUE;
/* disable double share regions */
if (entry->m_share != NULL)
for (i = 0; i < region_count; i++)
if (cheat_region[i].share != NULL)
- if (strcmp(cheat_region[i].share, entry->m_share)==0)
+ if (strcmp(cheat_region[i].share, entry->m_share) == 0)
cheat_region[region_count].disabled = TRUE;
region_count++;
@@ -1738,8 +1738,8 @@ static void execute_cheatinit(running_machine *machine, int ref, int params, con
return;
/* force region to the specified range */
- cheat_region[region_count].offset = memory_address_to_byte(space, offset) & space->bytemask;;
- cheat_region[region_count].endoffset = memory_address_to_byte(space, offset + length - 1) & space->bytemask;;
+ cheat_region[region_count].offset = space->address_to_byte(offset) & space->bytemask();
+ cheat_region[region_count].endoffset = space->address_to_byte(offset + length - 1) & space->bytemask();
cheat_region[region_count].share = NULL;
cheat_region[region_count].disabled = FALSE;
region_count++;
@@ -2000,7 +2000,7 @@ static void execute_cheatlist(running_machine *machine, int ref, int params, con
if (params > 0)
f = fopen(param[0], "w");
- switch (space->spacenum)
+ switch (space->spacenum())
{
default:
case ADDRESS_SPACE_PROGRAM: spaceletter = 'p'; break;
@@ -2023,19 +2023,19 @@ static void execute_cheatlist(running_machine *machine, int ref, int params, con
if (cheat.cheatmap[cheatindex].state == 1)
{
UINT64 value = cheat_byte_swap(&cheat, cheat_read_extended(&cheat, space, cheat.cheatmap[cheatindex].offset)) & sizemask;
- offs_t address = memory_byte_to_address(space, cheat.cheatmap[cheatindex].offset);
+ offs_t address = space->byte_to_address(cheat.cheatmap[cheatindex].offset);
if (params > 0)
{
active_cheat++;
- fprintf(f, " <cheat desc=\"Possibility %d : %s (%s)\">\n", active_cheat, core_i64_hex_format(address, space->logaddrchars), core_i64_hex_format(value, cheat.width * 2));
+ fprintf(f, " <cheat desc=\"Possibility %d : %s (%s)\">\n", active_cheat, core_i64_hex_format(address, space->logaddrchars()), core_i64_hex_format(value, cheat.width * 2));
fprintf(f, " <script state=\"run\">\n");
- fprintf(f, " <action>%s.p%c%c@%s=%s</action>\n", cpu->tag(), spaceletter, sizeletter, core_i64_hex_format(address, space->logaddrchars), core_i64_hex_format(cheat_byte_swap(&cheat, cheat.cheatmap[cheatindex].first_value) & sizemask, cheat.width * 2));
+ fprintf(f, " <action>%s.p%c%c@%s=%s</action>\n", cpu->tag(), spaceletter, sizeletter, core_i64_hex_format(address, space->logaddrchars()), core_i64_hex_format(cheat_byte_swap(&cheat, cheat.cheatmap[cheatindex].first_value) & sizemask, cheat.width * 2));
fprintf(f, " </script>\n");
fprintf(f, " </cheat>\n\n");
}
else
- debug_console_printf(machine, "Address=%s Start=%s Current=%s\n", core_i64_hex_format(address, space->logaddrchars), core_i64_hex_format(cheat_byte_swap(&cheat, cheat.cheatmap[cheatindex].first_value) & sizemask, cheat.width * 2), core_i64_hex_format(value, cheat.width * 2));
+ debug_console_printf(machine, "Address=%s Start=%s Current=%s\n", core_i64_hex_format(address, space->logaddrchars()), core_i64_hex_format(cheat_byte_swap(&cheat, cheat.cheatmap[cheatindex].first_value) & sizemask, cheat.width * 2), core_i64_hex_format(value, cheat.width * 2));
}
}
if (params > 0)
@@ -2096,9 +2096,9 @@ static void execute_find(running_machine *machine, int ref, int params, const ch
return;
/* further validation */
- endoffset = memory_address_to_byte(space, offset + length - 1) & space->bytemask;
- offset = memory_address_to_byte(space, offset) & space->bytemask;
- cur_data_size = memory_address_to_byte(space, 1);
+ endoffset = space->address_to_byte(offset + length - 1) & space->bytemask();
+ offset = space->address_to_byte(offset) & space->bytemask();
+ cur_data_size = space->address_to_byte(1);
if (cur_data_size == 0)
cur_data_size = 1;
@@ -2161,7 +2161,7 @@ static void execute_find(running_machine *machine, int ref, int params, const ch
if (match)
{
found++;
- debug_console_printf(machine, "Found at %s\n", core_i64_hex_format((UINT32)memory_byte_to_address(space, i), space->addrchars));
+ debug_console_printf(machine, "Found at %s\n", core_i64_hex_format((UINT32)space->byte_to_address(i), space->addrchars()));
}
}
@@ -2215,7 +2215,7 @@ static void execute_dasm(running_machine *machine, int ref, int params, const ch
/* now write the data out */
for (i = 0; i < length; )
{
- int pcbyte = memory_address_to_byte(space, offset + i) & space->bytemask;
+ int pcbyte = space->address_to_byte(offset + i) & space->bytemask();
char output[200+DEBUG_COMMENT_MAX_LINE_LENGTH], disasm[200];
const char *comment;
offs_t tempaddr;
@@ -2223,7 +2223,7 @@ static void execute_dasm(running_machine *machine, int ref, int params, const ch
int numbytes = 0;
/* print the address */
- outdex += sprintf(&output[outdex], "%s: ", core_i64_hex_format((UINT32)memory_byte_to_address(space, pcbyte), space->logaddrchars));
+ outdex += sprintf(&output[outdex], "%s: ", core_i64_hex_format((UINT32)space->byte_to_address(pcbyte), space->logaddrchars()));
/* make sure we can translate the address */
tempaddr = pcbyte;
@@ -2246,7 +2246,7 @@ static void execute_dasm(running_machine *machine, int ref, int params, const ch
if (bytes)
{
int startdex = outdex;
- numbytes = memory_address_to_byte(space, numbytes);
+ numbytes = space->address_to_byte(numbytes);
for (j = 0; j < numbytes; j += minbytes)
outdex += sprintf(&output[outdex], "%s ", core_i64_hex_format(debug_read_opcode(space, pcbyte + j, minbytes, FALSE), minbytes * 2));
if (outdex - startdex < byteswidth)
@@ -2394,7 +2394,7 @@ static void execute_history(running_machine *machine, int ref, int params, const
offs_t pc = debug->history_pc(-index);
/* fetch the bytes up to the maximum */
- offs_t pcbyte = memory_address_to_byte(space, pc) & space->bytemask;
+ offs_t pcbyte = space->address_to_byte(pc) & space->bytemask();
UINT8 opbuf[64], argbuf[64];
for (int numbytes = 0; numbytes < maxbytes; numbytes++)
{
@@ -2405,7 +2405,7 @@ static void execute_history(running_machine *machine, int ref, int params, const
char buffer[200];
debug->disassemble(buffer, pc, opbuf, argbuf);
- debug_console_printf(machine, "%s: %s\n", core_i64_hex_format(pc, space->logaddrchars), buffer);
+ debug_console_printf(machine, "%s: %s\n", core_i64_hex_format(pc, space->logaddrchars()), buffer);
}
}
@@ -2490,14 +2490,14 @@ static void execute_map(running_machine *machine, int ref, int params, const cha
for (intention = TRANSLATE_READ_DEBUG; intention <= TRANSLATE_FETCH_DEBUG; intention++)
{
static const char *const intnames[] = { "Read", "Write", "Fetch" };
- taddress = memory_address_to_byte(space, address) & space->bytemask;
+ taddress = space->address_to_byte(address) & space->bytemask();
if (debug_cpu_translate(space, intention, &taddress))
{
- const char *mapname = memory_get_handler_string(space, intention == TRANSLATE_WRITE_DEBUG, taddress);
- debug_console_printf(machine, "%7s: %s logical == %s physical -> %s\n", intnames[intention & 3], core_i64_hex_format(address, space->logaddrchars), core_i64_hex_format(memory_byte_to_address(space, taddress), space->addrchars), mapname);
+ const char *mapname = const_cast<address_space *>(space)->get_handler_string((intention == TRANSLATE_WRITE_DEBUG) ? ROW_WRITE : ROW_READ, taddress);
+ debug_console_printf(machine, "%7s: %s logical == %s physical -> %s\n", intnames[intention & 3], core_i64_hex_format(address, space->logaddrchars()), core_i64_hex_format(space->byte_to_address(taddress), space->addrchars()), mapname);
}
else
- debug_console_printf(machine, "%7s: %s logical is unmapped\n", intnames[intention & 3], core_i64_hex_format(address, space->logaddrchars));
+ debug_console_printf(machine, "%7s: %s logical is unmapped\n", intnames[intention & 3], core_i64_hex_format(address, space->logaddrchars()));
}
}
diff --git a/src/emu/debug/debugcmt.c b/src/emu/debug/debugcmt.c
index 7018d22e6b3..b2e2edb3b17 100644
--- a/src/emu/debug/debugcmt.c
+++ b/src/emu/debug/debugcmt.c
@@ -289,7 +289,7 @@ UINT32 debug_comment_get_opcode_crc32(device_t *device, offs_t address)
offs_t numbytes;
cpu_device *cpudevice = downcast<cpu_device *>(device);
int maxbytes = cpudevice->max_opcode_bytes();
- UINT32 addrmask = space->logaddrmask;
+ UINT32 addrmask = space->logaddrmask();
memset(opbuf, 0x00, sizeof(opbuf));
memset(argbuf, 0x00, sizeof(argbuf));
@@ -302,7 +302,7 @@ UINT32 debug_comment_get_opcode_crc32(device_t *device, offs_t address)
}
numbytes = device->debug()->disassemble(buff, address & addrmask, opbuf, argbuf) & DASMFLAG_LENGTHMASK;
- numbytes = memory_address_to_byte(space, numbytes);
+ numbytes = space->address_to_byte(numbytes);
crc = crc32(0, argbuf, numbytes);
diff --git a/src/emu/debug/debugcpu.c b/src/emu/debug/debugcpu.c
index 2a5c02a4858..31c0d3a9195 100644
--- a/src/emu/debug/debugcpu.c
+++ b/src/emu/debug/debugcpu.c
@@ -81,10 +81,10 @@ struct _debugcpu_private
symbol_table * symtable; /* global symbol table */
- UINT8 within_instruction_hook;
- UINT8 vblank_occurred;
- UINT8 memory_modified;
- UINT8 debugger_access;
+ bool within_instruction_hook;
+ bool vblank_occurred;
+ bool memory_modified;
+ bool debugger_access;
int execution_state;
@@ -243,14 +243,14 @@ int debug_cpu_within_instruction_hook(running_machine *machine)
/*-------------------------------------------------
- debug_cpu_is_stopped - return TRUE if the
+ debug_cpu_is_stopped - return true if the
current execution state is stopped
-------------------------------------------------*/
int debug_cpu_is_stopped(running_machine *machine)
{
debugcpu_private *global = machine->debugcpu_data;
- return (global != NULL) ? (global->execution_state == EXECUTION_STATE_STOPPED) : FALSE;
+ return (global != NULL) ? (global->execution_state == EXECUTION_STATE_STOPPED) : false;
}
@@ -327,8 +327,8 @@ int debug_cpu_translate(const address_space *space, int intention, offs_t *addre
{
device_memory_interface *memory;
if (space->cpu->interface(memory))
- return memory->translate(space->spacenum, intention, *address);
- return TRUE;
+ return memory->translate(space->spacenum(), intention, *address);
+ return true;
}
@@ -341,32 +341,33 @@ int debug_cpu_translate(const address_space *space, int intention, offs_t *addre
the specified memory space
-------------------------------------------------*/
-UINT8 debug_read_byte(const address_space *space, offs_t address, int apply_translation)
+UINT8 debug_read_byte(const address_space *_space, offs_t address, int apply_translation)
{
+ address_space *space = const_cast<address_space *>(_space);
debugcpu_private *global = space->machine->debugcpu_data;
UINT64 custom;
UINT8 result;
/* mask against the logical byte mask */
- address &= space->logbytemask;
+ address &= space->logbytemask();
/* all accesses from this point on are for the debugger */
- memory_set_debugger_access(space, global->debugger_access = TRUE);
+ space->set_debugger_access(global->debugger_access = true);
/* translate if necessary; if not mapped, return 0xff */
if (apply_translation && !debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
result = 0xff;
- /* if there is a custom read handler, and it returns TRUE, use that value */
- else if (device_memory(space->cpu)->read(space->spacenum, address, 1, custom))
+ /* if there is a custom read handler, and it returns true, use that value */
+ else if (device_memory(space->cpu)->read(space->spacenum(), address, 1, custom))
result = custom;
/* otherwise, call the byte reading function for the translated address */
else
- result = memory_read_byte(space, address);
+ result = space->read_byte(address);
/* no longer accessing via the debugger */
- memory_set_debugger_access(space, global->debugger_access = FALSE);
+ space->set_debugger_access(global->debugger_access = false);
return result;
}
@@ -376,13 +377,14 @@ UINT8 debug_read_byte(const address_space *space, offs_t address, int apply_tran
specified memory space
-------------------------------------------------*/
-UINT16 debug_read_word(const address_space *space, offs_t address, int apply_translation)
+UINT16 debug_read_word(const address_space *_space, offs_t address, int apply_translation)
{
+ address_space *space = const_cast<address_space *>(_space);
debugcpu_private *global = space->machine->debugcpu_data;
UINT16 result;
/* mask against the logical byte mask */
- address &= space->logbytemask;
+ address &= space->logbytemask();
/* if this is misaligned read, or if there are no word readers, just read two bytes */
if ((address & 1) != 0)
@@ -391,7 +393,7 @@ UINT16 debug_read_word(const address_space *space, offs_t address, int apply_tra
UINT8 byte1 = debug_read_byte(space, address + 1, apply_translation);
/* based on the endianness, the result is assembled differently */
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
result = byte0 | (byte1 << 8);
else
result = byte1 | (byte0 << 8);
@@ -403,22 +405,22 @@ UINT16 debug_read_word(const address_space *space, offs_t address, int apply_tra
UINT64 custom;
/* all accesses from this point on are for the debugger */
- memory_set_debugger_access(space, global->debugger_access = TRUE);
+ space->set_debugger_access(global->debugger_access = true);
/* translate if necessary; if not mapped, return 0xffff */
if (apply_translation && !debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
result = 0xffff;
- /* if there is a custom read handler, and it returns TRUE, use that value */
- else if (device_memory(space->cpu)->read(space->spacenum, address, 2, custom))
+ /* if there is a custom read handler, and it returns true, use that value */
+ else if (device_memory(space->cpu)->read(space->spacenum(), address, 2, custom))
result = custom;
/* otherwise, call the byte reading function for the translated address */
else
- result = memory_read_word(space, address);
+ result = space->read_word(address);
/* no longer accessing via the debugger */
- memory_set_debugger_access(space, global->debugger_access = FALSE);
+ space->set_debugger_access(global->debugger_access = false);
}
return result;
@@ -430,13 +432,14 @@ UINT16 debug_read_word(const address_space *space, offs_t address, int apply_tra
specified memory space
-------------------------------------------------*/
-UINT32 debug_read_dword(const address_space *space, offs_t address, int apply_translation)
+UINT32 debug_read_dword(const address_space *_space, offs_t address, int apply_translation)
{
+ address_space *space = const_cast<address_space *>(_space);
debugcpu_private *global = space->machine->debugcpu_data;
UINT32 result;
/* mask against the logical byte mask */
- address &= space->logbytemask;
+ address &= space->logbytemask();
/* if this is misaligned read, or if there are no dword readers, just read two words */
if ((address & 3) != 0)
@@ -445,7 +448,7 @@ UINT32 debug_read_dword(const address_space *space, offs_t address, int apply_tr
UINT16 word1 = debug_read_word(space, address + 2, apply_translation);
/* based on the endianness, the result is assembled differently */
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
result = word0 | (word1 << 16);
else
result = word1 | (word0 << 16);
@@ -457,22 +460,22 @@ UINT32 debug_read_dword(const address_space *space, offs_t address, int apply_tr
UINT64 custom;
/* all accesses from this point on are for the debugger */
- memory_set_debugger_access(space, global->debugger_access = TRUE);
+ space->set_debugger_access(global->debugger_access = true);
/* translate if necessary; if not mapped, return 0xffffffff */
if (apply_translation && !debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
result = 0xffffffff;
- /* if there is a custom read handler, and it returns TRUE, use that value */
- else if (device_memory(space->cpu)->read(space->spacenum, address, 4, custom))
+ /* if there is a custom read handler, and it returns true, use that value */
+ else if (device_memory(space->cpu)->read(space->spacenum(), address, 4, custom))
result = custom;
/* otherwise, call the byte reading function for the translated address */
else
- result = memory_read_dword(space, address);
+ result = space->read_dword(address);
/* no longer accessing via the debugger */
- memory_set_debugger_access(space, global->debugger_access = FALSE);
+ space->set_debugger_access(global->debugger_access = false);
}
return result;
@@ -484,13 +487,14 @@ UINT32 debug_read_dword(const address_space *space, offs_t address, int apply_tr
specified memory space
-------------------------------------------------*/
-UINT64 debug_read_qword(const address_space *space, offs_t address, int apply_translation)
+UINT64 debug_read_qword(const address_space *_space, offs_t address, int apply_translation)
{
+ address_space *space = const_cast<address_space *>(_space);
debugcpu_private *global = space->machine->debugcpu_data;
UINT64 result;
/* mask against the logical byte mask */
- address &= space->logbytemask;
+ address &= space->logbytemask();
/* if this is misaligned read, or if there are no qword readers, just read two dwords */
if ((address & 7) != 0)
@@ -499,7 +503,7 @@ UINT64 debug_read_qword(const address_space *space, offs_t address, int apply_tr
UINT32 dword1 = debug_read_dword(space, address + 4, apply_translation);
/* based on the endianness, the result is assembled differently */
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
result = dword0 | ((UINT64)dword1 << 32);
else
result = dword1 | ((UINT64)dword0 << 32);
@@ -511,22 +515,22 @@ UINT64 debug_read_qword(const address_space *space, offs_t address, int apply_tr
UINT64 custom;
/* all accesses from this point on are for the debugger */
- memory_set_debugger_access(space, global->debugger_access = TRUE);
+ space->set_debugger_access(global->debugger_access = true);
/* translate if necessary; if not mapped, return 0xffffffffffffffff */
if (apply_translation && !debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
result = ~(UINT64)0;
- /* if there is a custom read handler, and it returns TRUE, use that value */
- else if (device_memory(space->cpu)->read(space->spacenum, address, 8, custom))
+ /* if there is a custom read handler, and it returns true, use that value */
+ else if (device_memory(space->cpu)->read(space->spacenum(), address, 8, custom))
result = custom;
/* otherwise, call the byte reading function for the translated address */
else
- result = memory_read_qword(space, address);
+ result = space->read_qword(address);
/* no longer accessing via the debugger */
- memory_set_debugger_access(space, global->debugger_access = FALSE);
+ space->set_debugger_access(global->debugger_access = false);
}
return result;
@@ -557,31 +561,32 @@ UINT64 debug_read_memory(const address_space *space, offs_t address, int size, i
specified memory space
-------------------------------------------------*/
-void debug_write_byte(const address_space *space, offs_t address, UINT8 data, int apply_translation)
+void debug_write_byte(const address_space *_space, offs_t address, UINT8 data, int apply_translation)
{
+ address_space *space = const_cast<address_space *>(_space);
debugcpu_private *global = space->machine->debugcpu_data;
/* mask against the logical byte mask */
- address &= space->logbytemask;
+ address &= space->logbytemask();
/* all accesses from this point on are for the debugger */
- memory_set_debugger_access(space, global->debugger_access = TRUE);
+ space->set_debugger_access(global->debugger_access = true);
/* translate if necessary; if not mapped, we're done */
if (apply_translation && !debug_cpu_translate(space, TRANSLATE_WRITE_DEBUG, &address))
;
- /* if there is a custom write handler, and it returns TRUE, use that */
- else if (device_memory(space->cpu)->write(space->spacenum, address, 1, data))
+ /* if there is a custom write handler, and it returns true, use that */
+ else if (device_memory(space->cpu)->write(space->spacenum(), address, 1, data))
;
/* otherwise, call the byte reading function for the translated address */
else
- memory_write_byte(space, address, data);
+ space->write_byte(address, data);
/* no longer accessing via the debugger */
- memory_set_debugger_access(space, global->debugger_access = FALSE);
- global->memory_modified = TRUE;
+ space->set_debugger_access(global->debugger_access = false);
+ global->memory_modified = true;
}
@@ -590,17 +595,18 @@ void debug_write_byte(const address_space *space, offs_t address, UINT8 data, in
specified memory space
-------------------------------------------------*/
-void debug_write_word(const address_space *space, offs_t address, UINT16 data, int apply_translation)
+void debug_write_word(const address_space *_space, offs_t address, UINT16 data, int apply_translation)
{
+ address_space *space = const_cast<address_space *>(_space);
debugcpu_private *global = space->machine->debugcpu_data;
/* mask against the logical byte mask */
- address &= space->logbytemask;
+ address &= space->logbytemask();
/* if this is a misaligned write, or if there are no word writers, just read two bytes */
if ((address & 1) != 0)
{
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
{
debug_write_byte(space, address + 0, data >> 0, apply_translation);
debug_write_byte(space, address + 1, data >> 8, apply_translation);
@@ -616,23 +622,23 @@ void debug_write_word(const address_space *space, offs_t address, UINT16 data, i
else
{
/* all accesses from this point on are for the debugger */
- memory_set_debugger_access(space, global->debugger_access = TRUE);
+ space->set_debugger_access(global->debugger_access = true);
/* translate if necessary; if not mapped, we're done */
if (apply_translation && !debug_cpu_translate(space, TRANSLATE_WRITE_DEBUG, &address))
;
- /* if there is a custom write handler, and it returns TRUE, use that */
- else if (device_memory(space->cpu)->write(space->spacenum, address, 2, data))
+ /* if there is a custom write handler, and it returns true, use that */
+ else if (device_memory(space->cpu)->write(space->spacenum(), address, 2, data))
;
/* otherwise, call the byte reading function for the translated address */
else
- memory_write_word(space, address, data);
+ space->write_word(address, data);
/* no longer accessing via the debugger */
- memory_set_debugger_access(space, global->debugger_access = FALSE);
- global->memory_modified = TRUE;
+ space->set_debugger_access(global->debugger_access = false);
+ global->memory_modified = true;
}
}
@@ -642,17 +648,18 @@ void debug_write_word(const address_space *space, offs_t address, UINT16 data, i
specified memory space
-------------------------------------------------*/
-void debug_write_dword(const address_space *space, offs_t address, UINT32 data, int apply_translation)
+void debug_write_dword(const address_space *_space, offs_t address, UINT32 data, int apply_translation)
{
+ address_space *space = const_cast<address_space *>(_space);
debugcpu_private *global = space->machine->debugcpu_data;
/* mask against the logical byte mask */
- address &= space->logbytemask;
+ address &= space->logbytemask();
/* if this is a misaligned write, or if there are no dword writers, just read two words */
if ((address & 3) != 0)
{
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
{
debug_write_word(space, address + 0, data >> 0, apply_translation);
debug_write_word(space, address + 2, data >> 16, apply_translation);
@@ -668,23 +675,23 @@ void debug_write_dword(const address_space *space, offs_t address, UINT32 data,
else
{
/* all accesses from this point on are for the debugger */
- memory_set_debugger_access(space, global->debugger_access = TRUE);
+ space->set_debugger_access(global->debugger_access = true);
/* translate if necessary; if not mapped, we're done */
if (apply_translation && !debug_cpu_translate(space, TRANSLATE_WRITE_DEBUG, &address))
;
- /* if there is a custom write handler, and it returns TRUE, use that */
- else if (device_memory(space->cpu)->write(space->spacenum, address, 4, data))
+ /* if there is a custom write handler, and it returns true, use that */
+ else if (device_memory(space->cpu)->write(space->spacenum(), address, 4, data))
;
/* otherwise, call the byte reading function for the translated address */
else
- memory_write_dword(space, address, data);
+ space->write_dword(address, data);
/* no longer accessing via the debugger */
- memory_set_debugger_access(space, global->debugger_access = FALSE);
- global->memory_modified = TRUE;
+ space->set_debugger_access(global->debugger_access = false);
+ global->memory_modified = true;
}
}
@@ -694,17 +701,18 @@ void debug_write_dword(const address_space *space, offs_t address, UINT32 data,
specified memory space
-------------------------------------------------*/
-void debug_write_qword(const address_space *space, offs_t address, UINT64 data, int apply_translation)
+void debug_write_qword(const address_space *_space, offs_t address, UINT64 data, int apply_translation)
{
+ address_space *space = const_cast<address_space *>(_space);
debugcpu_private *global = space->machine->debugcpu_data;
/* mask against the logical byte mask */
- address &= space->logbytemask;
+ address &= space->logbytemask();
/* if this is a misaligned write, or if there are no qword writers, just read two dwords */
if ((address & 7) != 0)
{
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
{
debug_write_dword(space, address + 0, data >> 0, apply_translation);
debug_write_dword(space, address + 4, data >> 32, apply_translation);
@@ -720,23 +728,23 @@ void debug_write_qword(const address_space *space, offs_t address, UINT64 data,
else
{
/* all accesses from this point on are for the debugger */
- memory_set_debugger_access(space, global->debugger_access = TRUE);
+ space->set_debugger_access(global->debugger_access = true);
/* translate if necessary; if not mapped, we're done */
if (apply_translation && !debug_cpu_translate(space, TRANSLATE_WRITE_DEBUG, &address))
;
- /* if there is a custom write handler, and it returns TRUE, use that */
- else if (device_memory(space->cpu)->write(space->spacenum, address, 8, data))
+ /* if there is a custom write handler, and it returns true, use that */
+ else if (device_memory(space->cpu)->write(space->spacenum(), address, 8, data))
;
/* otherwise, call the byte reading function for the translated address */
else
- memory_write_qword(space, address, data);
+ space->write_qword(address, data);
/* no longer accessing via the debugger */
- memory_set_debugger_access(space, global->debugger_access = FALSE);
- global->memory_modified = TRUE;
+ space->set_debugger_access(global->debugger_access = false);
+ global->memory_modified = true;
}
}
@@ -763,31 +771,32 @@ void debug_write_memory(const address_space *space, offs_t address, UINT64 data,
the given offset from opcode space
-------------------------------------------------*/
-UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, int arg)
+UINT64 debug_read_opcode(const address_space *_space, offs_t address, int size, int arg)
{
+ address_space *space = const_cast<address_space *>(_space);
UINT64 result = ~(UINT64)0 & (~(UINT64)0 >> (64 - 8*size)), result2;
debugcpu_private *global = space->machine->debugcpu_data;
/* keep in logical range */
- address &= space->logbytemask;
+ address &= space->logbytemask();
/* return early if we got the result directly */
- memory_set_debugger_access(space, global->debugger_access = TRUE);
+ space->set_debugger_access(global->debugger_access = true);
device_memory_interface *memory;
if (space->cpu->interface(memory) && memory->readop(address, size, result2))
{
- memory_set_debugger_access(space, global->debugger_access = FALSE);
+ space->set_debugger_access(global->debugger_access = false);
return result2;
}
/* if we're bigger than the address bus, break into smaller pieces */
- if (size > space->dbits / 8)
+ if (size > space->data_width() / 8)
{
int halfsize = size / 2;
UINT64 r0 = debug_read_opcode(space, address + 0, halfsize, arg);
UINT64 r1 = debug_read_opcode(space, address + halfsize, halfsize, arg);
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
return r0 | (r1 << (8 * halfsize));
else
return r1 | (r0 << (8 * halfsize));
@@ -798,8 +807,8 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
return result;
/* keep in physical range */
- address &= space->bytemask;
- switch (space->dbits / 8 * 10 + size)
+ address &= space->bytemask();
+ switch (space->data_width() / 8 * 10 + size)
{
/* dump opcodes in bytes from a byte-sized bus */
case 11:
@@ -807,7 +816,7 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
/* dump opcodes in bytes from a word-sized bus */
case 21:
- address ^= (space->endianness == ENDIANNESS_LITTLE) ? BYTE_XOR_LE(0) : BYTE_XOR_BE(0);
+ address ^= (space->endianness() == ENDIANNESS_LITTLE) ? BYTE_XOR_LE(0) : BYTE_XOR_BE(0);
break;
/* dump opcodes in words from a word-sized bus */
@@ -816,12 +825,12 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
/* dump opcodes in bytes from a dword-sized bus */
case 41:
- address ^= (space->endianness == ENDIANNESS_LITTLE) ? BYTE4_XOR_LE(0) : BYTE4_XOR_BE(0);
+ address ^= (space->endianness() == ENDIANNESS_LITTLE) ? BYTE4_XOR_LE(0) : BYTE4_XOR_BE(0);
break;
/* dump opcodes in words from a dword-sized bus */
case 42:
- address ^= (space->endianness == ENDIANNESS_LITTLE) ? WORD_XOR_LE(0) : WORD_XOR_BE(0);
+ address ^= (space->endianness() == ENDIANNESS_LITTLE) ? WORD_XOR_LE(0) : WORD_XOR_BE(0);
break;
/* dump opcodes in dwords from a dword-sized bus */
@@ -830,17 +839,17 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
/* dump opcodes in bytes from a qword-sized bus */
case 81:
- address ^= (space->endianness == ENDIANNESS_LITTLE) ? BYTE8_XOR_LE(0) : BYTE8_XOR_BE(0);
+ address ^= (space->endianness() == ENDIANNESS_LITTLE) ? BYTE8_XOR_LE(0) : BYTE8_XOR_BE(0);
break;
/* dump opcodes in words from a qword-sized bus */
case 82:
- address ^= (space->endianness == ENDIANNESS_LITTLE) ? WORD2_XOR_LE(0) : WORD2_XOR_BE(0);
+ address ^= (space->endianness() == ENDIANNESS_LITTLE) ? WORD2_XOR_LE(0) : WORD2_XOR_BE(0);
break;
/* dump opcodes in dwords from a qword-sized bus */
case 84:
- address ^= (space->endianness == ENDIANNESS_LITTLE) ? DWORD_XOR_LE(0) : DWORD_XOR_BE(0);
+ address ^= (space->endianness() == ENDIANNESS_LITTLE) ? DWORD_XOR_LE(0) : DWORD_XOR_BE(0);
break;
/* dump opcodes in qwords from a qword-sized bus */
@@ -848,13 +857,13 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
break;
default:
- fatalerror("debug_read_opcode: unknown type = %d", space->dbits / 8 * 10 + size);
+ fatalerror("debug_read_opcode: unknown type = %d", space->data_width() / 8 * 10 + size);
break;
}
/* turn on debugger access */
if (!global->debugger_access)
- memory_set_debugger_access(space, global->debugger_access = TRUE);
+ space->set_debugger_access(global->debugger_access = true);
/* switch off the size and handle unaligned accesses */
switch (size)
@@ -868,7 +877,7 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
if ((address & 1) != 0)
{
result2 = (arg) ? memory_raw_read_word(space, (address & ~1) + 2) : memory_decrypted_read_word(space, (address & ~1) + 2);
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
result = (result >> (8 * (address & 1))) | (result2 << (16 - 8 * (address & 1)));
else
result = (result << (8 * (address & 1))) | (result2 >> (16 - 8 * (address & 1)));
@@ -881,7 +890,7 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
if ((address & 3) != 0)
{
result2 = (arg) ? memory_raw_read_dword(space, (address & ~3) + 4) : memory_decrypted_read_dword(space, (address & ~3) + 4);
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
result = (result >> (8 * (address & 3))) | (result2 << (32 - 8 * (address & 3)));
else
result = (result << (8 * (address & 3))) | (result2 >> (32 - 8 * (address & 3)));
@@ -894,7 +903,7 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
if ((address & 7) != 0)
{
result2 = (arg) ? memory_raw_read_qword(space, (address & ~7) + 8) : memory_decrypted_read_qword(space, (address & ~7) + 8);
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
result = (result >> (8 * (address & 7))) | (result2 << (64 - 8 * (address & 7)));
else
result = (result << (8 * (address & 7))) | (result2 >> (64 - 8 * (address & 7)));
@@ -903,7 +912,7 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
}
/* no longer accessing via the debugger */
- memory_set_debugger_access(space, global->debugger_access = FALSE);
+ space->set_debugger_access(global->debugger_access = false);
return result;
}
@@ -935,7 +944,7 @@ static void on_vblank(screen_device &device, void *param, bool vblank_state)
{
/* just set a global flag to be consumed later */
if (vblank_state)
- device.machine->debugcpu_data->vblank_occurred = TRUE;
+ device.machine->debugcpu_data->vblank_occurred = true;
}
@@ -1044,7 +1053,7 @@ static UINT64 expression_read_memory(void *param, const char *name, int spacenum
device = debug_cpu_get_visible_cpu(machine);
space = cpu_get_address_space(device, ADDRESS_SPACE_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL));
if (space != NULL)
- result = debug_read_memory(space, memory_address_to_byte(space, address), size, TRUE);
+ result = debug_read_memory(space, space->address_to_byte(address), size, true);
break;
case EXPSPACE_PROGRAM_PHYSICAL:
@@ -1057,7 +1066,7 @@ static UINT64 expression_read_memory(void *param, const char *name, int spacenum
device = debug_cpu_get_visible_cpu(machine);
space = cpu_get_address_space(device, ADDRESS_SPACE_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL));
if (space != NULL)
- result = debug_read_memory(space, memory_address_to_byte(space, address), size, FALSE);
+ result = debug_read_memory(space, space->address_to_byte(address), size, false);
break;
case EXPSPACE_OPCODE:
@@ -1084,8 +1093,9 @@ static UINT64 expression_read_memory(void *param, const char *name, int spacenum
directly from an opcode or RAM pointer
-------------------------------------------------*/
-static UINT64 expression_read_program_direct(const address_space *space, int opcode, offs_t address, int size)
+static UINT64 expression_read_program_direct(const address_space *_space, int opcode, offs_t address, int size)
{
+ address_space *space = const_cast<address_space *>(_space);
UINT64 result = ~(UINT64)0 >> (64 - 8*size);
if (space != NULL)
@@ -1094,7 +1104,7 @@ static UINT64 expression_read_program_direct(const address_space *space, int opc
/* adjust the address into a byte address, but not if being called recursively */
if ((opcode & 2) == 0)
- address = memory_address_to_byte(space, address);
+ address = space->address_to_byte(address);
/* call ourself recursively until we are byte-sized */
if (size > 1)
@@ -1107,7 +1117,7 @@ static UINT64 expression_read_program_direct(const address_space *space, int opc
r1 = expression_read_program_direct(space, opcode | 2, address + halfsize, halfsize);
/* assemble based on the target endianness */
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
result = r0 | (r1 << (8 * halfsize));
else
result = r1 | (r0 << (8 * halfsize));
@@ -1117,7 +1127,7 @@ static UINT64 expression_read_program_direct(const address_space *space, int opc
else
{
/* lowmask specified which address bits are within the databus width */
- offs_t lowmask = space->dbits / 8 - 1;
+ offs_t lowmask = space->data_width() / 8 - 1;
/* get the base of memory, aligned to the address minus the lowbits */
if (opcode & 1)
@@ -1128,7 +1138,7 @@ static UINT64 expression_read_program_direct(const address_space *space, int opc
/* if we have a valid base, return the appropriate byte */
if (base != NULL)
{
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
result = base[BYTE8_XOR_LE(address) & lowmask];
else
result = base[BYTE8_XOR_BE(address) & lowmask];
@@ -1211,7 +1221,7 @@ static void expression_write_memory(void *param, const char *name, int spacenum,
device = debug_cpu_get_visible_cpu(machine);
space = cpu_get_address_space(device, ADDRESS_SPACE_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL));
if (space != NULL)
- debug_write_memory(space, memory_address_to_byte(space, address), data, size, TRUE);
+ debug_write_memory(space, space->address_to_byte(address), data, size, true);
break;
case EXPSPACE_PROGRAM_PHYSICAL:
@@ -1224,7 +1234,7 @@ static void expression_write_memory(void *param, const char *name, int spacenum,
device = debug_cpu_get_visible_cpu(machine);
space = cpu_get_address_space(device, ADDRESS_SPACE_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL));
if (space != NULL)
- debug_write_memory(space, memory_address_to_byte(space, address), data, size, FALSE);
+ debug_write_memory(space, space->address_to_byte(address), data, size, false);
break;
case EXPSPACE_OPCODE:
@@ -1250,8 +1260,9 @@ static void expression_write_memory(void *param, const char *name, int spacenum,
directly to an opcode or RAM pointer
-------------------------------------------------*/
-static void expression_write_program_direct(const address_space *space, int opcode, offs_t address, int size, UINT64 data)
+static void expression_write_program_direct(const address_space *_space, int opcode, offs_t address, int size, UINT64 data)
{
+ address_space *space = const_cast<address_space *>(_space);
if (space != NULL)
{
debugcpu_private *global = space->machine->debugcpu_data;
@@ -1259,7 +1270,7 @@ static void expression_write_program_direct(const address_space *space, int opco
/* adjust the address into a byte address, but not if being called recursively */
if ((opcode & 2) == 0)
- address = memory_address_to_byte(space, address);
+ address = space->address_to_byte(address);
/* call ourself recursively until we are byte-sized */
if (size > 1)
@@ -1269,7 +1280,7 @@ static void expression_write_program_direct(const address_space *space, int opco
/* break apart based on the target endianness */
halfmask = ~(UINT64)0 >> (64 - 8 * halfsize);
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
{
r0 = data & halfmask;
r1 = (data >> (8 * halfsize)) & halfmask;
@@ -1289,7 +1300,7 @@ static void expression_write_program_direct(const address_space *space, int opco
else
{
/* lowmask specified which address bits are within the databus width */
- offs_t lowmask = space->dbits / 8 - 1;
+ offs_t lowmask = space->data_width() / 8 - 1;
/* get the base of memory, aligned to the address minus the lowbits */
if (opcode & 1)
@@ -1300,11 +1311,11 @@ static void expression_write_program_direct(const address_space *space, int opco
/* if we have a valid base, write the appropriate byte */
if (base != NULL)
{
- if (space->endianness == ENDIANNESS_LITTLE)
+ if (space->endianness() == ENDIANNESS_LITTLE)
base[BYTE8_XOR_LE(address) & lowmask] = data;
else
base[BYTE8_XOR_BE(address) & lowmask] = data;
- global->memory_modified = TRUE;
+ global->memory_modified = true;
}
}
}
@@ -1360,7 +1371,7 @@ static void expression_write_memory_region(running_machine *machine, const char
base[BYTE8_XOR_LE(address) & lowmask] = data;
else
base[BYTE8_XOR_BE(address) & lowmask] = data;
- global->memory_modified = TRUE;
+ global->memory_modified = true;
}
}
}
@@ -1678,7 +1689,7 @@ void device_debug::start_hook(attotime endtime)
// if a VBLANK occurred, check on things
if (global->vblank_occurred)
{
- global->vblank_occurred = FALSE;
+ global->vblank_occurred = false;
// if we were waiting for a VBLANK, signal it now
if ((m_flags & DEBUG_FLAG_STOP_VBLANK) != 0)
@@ -1769,7 +1780,7 @@ void device_debug::instruction_hook(offs_t curpc)
debugcpu_private *global = m_device.machine->debugcpu_data;
// note that we are in the debugger code
- global->within_instruction_hook = TRUE;
+ global->within_instruction_hook = true;
// update the history
m_pc_history[m_pc_history_index++ % HISTORY_SIZE] = curpc;
@@ -1831,7 +1842,7 @@ void device_debug::instruction_hook(offs_t curpc)
// if we are supposed to halt, do it now
if (global->execution_state == EXECUTION_STATE_STOPPED)
{
- int firststop = TRUE;
+ int firststop = true;
// reset any transient state
reset_transient_flags(*m_device.machine);
@@ -1845,19 +1856,19 @@ void device_debug::instruction_hook(offs_t curpc)
debugger_refresh_display(m_device.machine);
// wait for the debugger; during this time, disable sound output
- sound_mute(m_device.machine, TRUE);
+ sound_mute(m_device.machine, true);
while (global->execution_state == EXECUTION_STATE_STOPPED)
{
// flush any pending updates before waiting again
m_device.machine->m_debug_view->flush_osd_updates();
// clear the memory modified flag and wait
- global->memory_modified = FALSE;
+ global->memory_modified = false;
if (m_device.machine->debug_flags & DEBUG_FLAG_OSD_ENABLED)
osd_wait_for_debugger(&m_device, firststop);
else if (m_device.machine->debug_flags & DEBUG_FLAG_ENABLED)
debugint_wait_for_debugger(&m_device, firststop);
- firststop = FALSE;
+ firststop = false;
// if something modified memory, update the screen
if (global->memory_modified)
@@ -1873,7 +1884,7 @@ void device_debug::instruction_hook(offs_t curpc)
if (m_device.machine->scheduled_event_pending())
global->execution_state = EXECUTION_STATE_RUNNING;
}
- sound_mute(m_device.machine, FALSE);
+ sound_mute(m_device.machine, false);
// remember the last visible CPU in the debugger
global->visiblecpu = &m_device;
@@ -1884,7 +1895,7 @@ void device_debug::instruction_hook(offs_t curpc)
prepare_for_step_overout(pc());
// no longer in debugger code
- global->within_instruction_hook = FALSE;
+ global->within_instruction_hook = false;
}
@@ -1956,7 +1967,7 @@ offs_t device_debug::disassemble(char *buffer, offs_t pc, const UINT8 *oprom, co
if (m_memory != NULL && m_disasm != NULL)
{
const address_space *space = m_memory->space(AS_PROGRAM);
- int bytes = memory_address_to_byte(space, result & DASMFLAG_LENGTHMASK);
+ int bytes = space->address_to_byte(result & DASMFLAG_LENGTHMASK);
assert(bytes >= m_disasm->min_opcode_bytes());
assert(bytes <= m_disasm->max_opcode_bytes());
(void) bytes; // appease compiler
@@ -2068,7 +2079,7 @@ void device_debug::go_vblank()
assert(m_exec != NULL);
- global->vblank_occurred = FALSE;
+ global->vblank_occurred = false;
m_flags |= DEBUG_FLAG_STOP_VBLANK;
global->execution_state = EXECUTION_STATE_RUNNING;
}
@@ -2270,14 +2281,14 @@ void device_debug::breakpoint_enable_all(bool enable)
int device_debug::watchpoint_set(const address_space &space, int type, offs_t address, offs_t length, parsed_expression *condition, const char *action)
{
- assert(space.spacenum < ARRAY_LENGTH(m_wplist));
+ assert(space.spacenum() < ARRAY_LENGTH(m_wplist));
// allocate a new one
watchpoint *wp = auto_alloc(m_device.machine, watchpoint(m_device.machine->debugcpu_data->bpindex++, space, type, address, length, condition, action));
// hook it into our list
- wp->m_next = m_wplist[space.spacenum];
- m_wplist[space.spacenum] = wp;
+ wp->m_next = m_wplist[space.spacenum()];
+ m_wplist[space.spacenum()] = wp;
// update the flags and return the index
watchpoint_update_flags(wp->m_space);
@@ -2571,7 +2582,7 @@ void device_debug::watchpoint_update_flags(const address_space &space)
// see if there are any enabled breakpoints
bool enablewrite = false;
- for (watchpoint *wp = m_wplist[space.spacenum]; wp != NULL; wp = wp->m_next)
+ for (watchpoint *wp = m_wplist[space.spacenum()]; wp != NULL; wp = wp->m_next)
if (wp->m_enabled)
{
if (wp->m_type & WATCHPOINT_READ)
@@ -2598,13 +2609,13 @@ void device_debug::watchpoint_check(const address_space &space, int type, offs_t
// if we're within debugger code, don't stop
if (global->within_instruction_hook || global->debugger_access)
return;
- global->within_instruction_hook = TRUE;
+ global->within_instruction_hook = true;
// adjust address, size & value_to_write based on mem_mask.
offs_t size = 0;
if (mem_mask != 0)
{
- int bus_size = space.dbits / 8;
+ int bus_size = space.data_width() / 8;
int address_offset = 0;
while (address_offset < bus_size && (mem_mask & 0xff) == 0)
@@ -2620,7 +2631,7 @@ void device_debug::watchpoint_check(const address_space &space, int type, offs_t
mem_mask >>= 8;
}
- if (space.endianness == ENDIANNESS_LITTLE)
+ if (space.endianness() == ENDIANNESS_LITTLE)
address += address_offset;
else
address += bus_size - size - address_offset;
@@ -2632,7 +2643,7 @@ void device_debug::watchpoint_check(const address_space &space, int type, offs_t
global->wpdata = value_to_write;
// see if we match
- for (watchpoint *wp = m_wplist[space.spacenum]; wp != NULL; wp = wp->m_next)
+ for (watchpoint *wp = m_wplist[space.spacenum()]; wp != NULL; wp = wp->m_next)
if (wp->hit(type, address, size))
{
// halt in the debugger by default
@@ -2654,21 +2665,21 @@ void device_debug::watchpoint_check(const address_space &space, int type, offs_t
if (type & WATCHPOINT_WRITE)
{
- buffer.printf("Stopped at watchpoint %X writing %s to %08X (PC=%X)", wp->m_index, sizes[size], memory_byte_to_address(&space, address), pc);
+ buffer.printf("Stopped at watchpoint %X writing %s to %08X (PC=%X)", wp->m_index, sizes[size], space.byte_to_address(address), pc);
if (value_to_write >> 32)
buffer.catprintf(" (data=%X%08X)", (UINT32)(value_to_write >> 32), (UINT32)value_to_write);
else
buffer.catprintf(" (data=%X)", (UINT32)value_to_write);
}
else
- buffer.printf("Stopped at watchpoint %X reading %s from %08X (PC=%X)", wp->m_index, sizes[size], memory_byte_to_address(&space, address), pc);
+ buffer.printf("Stopped at watchpoint %X reading %s from %08X (PC=%X)", wp->m_index, sizes[size], space.byte_to_address(address), pc);
debug_console_printf(space.machine, "%s\n", buffer.cstr());
space.cpu->debug()->compute_debug_flags();
}
break;
}
- global->within_instruction_hook = FALSE;
+ global->within_instruction_hook = false;
}
@@ -2693,7 +2704,7 @@ void device_debug::hotspot_check(const address_space &space, offs_t address)
// if the bottom of the list is over the threshhold, print it
hotspot_entry &spot = m_hotspots[m_hotspot_count - 1];
if (spot.m_count > m_hotspot_threshhold)
- debug_console_printf(space.machine, "Hotspot @ %s %08X (PC=%08X) hit %d times (fell off bottom)\n", space.name, spot.m_access, spot.m_pc, spot.m_count);
+ debug_console_printf(space.machine, "Hotspot @ %s %08X (PC=%08X) hit %d times (fell off bottom)\n", space.name(), spot.m_access, spot.m_pc, spot.m_count);
// move everything else down and insert this one at the top
memmove(&m_hotspots[1], &m_hotspots[0], sizeof(m_hotspots[0]) * (m_hotspot_count - 1));
@@ -2729,15 +2740,15 @@ UINT32 device_debug::dasm_wrapped(astring &buffer, offs_t pc)
// determine the adjusted PC
const address_space *space = m_memory->space(AS_PROGRAM);
- offs_t pcbyte = memory_address_to_byte(space, pc) & space->bytemask;
+ offs_t pcbyte = space->address_to_byte(pc) & space->bytemask();
// fetch the bytes up to the maximum
UINT8 opbuf[64], argbuf[64];
int maxbytes = max_opcode_bytes();
for (int numbytes = 0; numbytes < maxbytes; numbytes++)
{
- opbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, FALSE);
- argbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, TRUE);
+ opbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, false);
+ argbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, true);
}
// disassemble to our buffer
@@ -2789,8 +2800,8 @@ UINT64 device_debug::get_logunmap(void *globalref, void *ref)
void device_debug::set_logunmap(void *globalref, void *ref, UINT64 value)
{
- const address_space *space = reinterpret_cast<const address_space *>(ref);
- memory_set_log_unmap(space, value ? 1 : 0);
+ address_space *space = reinterpret_cast<address_space *>(ref);
+ space->set_log_unmap(value ? true : false);
}
@@ -2887,8 +2898,8 @@ device_debug::watchpoint::watchpoint(int index, const address_space &space, int
m_index(index),
m_enabled(true),
m_type(type),
- m_address(memory_address_to_byte(&space, address) & space.bytemask),
- m_length(memory_address_to_byte(&space, length)),
+ m_address(space.address_to_byte(address) & space.bytemask()),
+ m_length(space.address_to_byte(length)),
m_condition(condition),
m_action((action != NULL) ? action : "")
{
diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h
index c25333fa79f..1373aaabfdf 100644
--- a/src/emu/debug/debugcpu.h
+++ b/src/emu/debug/debugcpu.h
@@ -146,7 +146,7 @@ public:
// commonly-used pass-throughs
offs_t pc() const { return (m_state != NULL) ? m_state->pc() : 0; }
- int logaddrchars(int spacenum = AS_PROGRAM) const { return (m_memory != NULL && m_memory->space(spacenum) != NULL) ? m_memory->space(spacenum)->logaddrchars : 8; }
+ int logaddrchars(int spacenum = AS_PROGRAM) const { return (m_memory != NULL && m_memory->space(spacenum) != NULL) ? m_memory->space(spacenum)->logaddrchars() : 8; }
int min_opcode_bytes() const { return (m_disasm != NULL) ? m_disasm->max_opcode_bytes() : 1; }
int max_opcode_bytes() const { return (m_disasm != NULL) ? m_disasm->max_opcode_bytes() : 1; }
diff --git a/src/emu/debug/dvdisasm.c b/src/emu/debug/dvdisasm.c
index 762f7f81b16..3e1dae3d178 100644
--- a/src/emu/debug/dvdisasm.c
+++ b/src/emu/debug/dvdisasm.c
@@ -203,7 +203,7 @@ void debug_view_disasm::view_char(int chval)
case DCH_HOME: // set the active column to the PC
{
const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);
- offs_t pc = memory_address_to_byte(source.m_space, cpu_get_pc(&source.m_device)) & source.m_space->logbytemask;
+ offs_t pc = source.m_space->address_to_byte(cpu_get_pc(&source.m_device)) & source.m_space->logbytemask();
// figure out which row the pc is on
for (int curline = 0; curline < m_allocated.y; curline++)
@@ -242,9 +242,9 @@ offs_t debug_view_disasm::find_pc_backwards(offs_t targetpc, int numinstrs)
const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);
// compute the increment
- int minlen = memory_byte_to_address(source.m_space, source.m_disasmintf->min_opcode_bytes());
+ int minlen = source.m_space->byte_to_address(source.m_disasmintf->min_opcode_bytes());
if (minlen == 0) minlen = 1;
- int maxlen = memory_byte_to_address(source.m_space, source.m_disasmintf->max_opcode_bytes());
+ int maxlen = source.m_space->byte_to_address(source.m_disasmintf->max_opcode_bytes());
if (maxlen == 0) maxlen = 1;
// start off numinstrs back
@@ -253,13 +253,13 @@ offs_t debug_view_disasm::find_pc_backwards(offs_t targetpc, int numinstrs)
curpc = 0;
/* loop until we find what we are looking for */
- offs_t targetpcbyte = memory_address_to_byte(source.m_space, targetpc) & source.m_space->logbytemask;
+ offs_t targetpcbyte = source.m_space->address_to_byte(targetpc) & source.m_space->logbytemask();
offs_t fillpcbyte = targetpcbyte;
offs_t lastgoodpc = targetpc;
while (1)
{
// fill the buffer up to the target
- offs_t curpcbyte = memory_address_to_byte(source.m_space, curpc) & source.m_space->logbytemask;
+ offs_t curpcbyte = source.m_space->address_to_byte(curpc) & source.m_space->logbytemask();
UINT8 opbuf[1024], argbuf[1024];
while (curpcbyte < fillpcbyte)
{
@@ -274,7 +274,7 @@ offs_t debug_view_disasm::find_pc_backwards(offs_t targetpc, int numinstrs)
offs_t scanpc;
for (scanpc = curpc; scanpc < targetpc; scanpc += instlen)
{
- offs_t scanpcbyte = memory_address_to_byte(source.m_space, scanpc) & source.m_space->logbytemask;
+ offs_t scanpcbyte = source.m_space->address_to_byte(scanpc) & source.m_space->logbytemask();
offs_t physpcbyte = scanpcbyte;
// get the disassembly, but only if mapped
@@ -348,7 +348,7 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines)
const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);
// determine how many characters we need for an address and set the divider
- m_divider1 = 1 + source.m_space->logaddrchars + 1;
+ m_divider1 = 1 + source.m_space->logaddrchars() + 1;
// assume a fixed number of characters for the disassembly
m_divider2 = m_divider1 + 1 + m_dasm_width + 1;
@@ -358,7 +358,7 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines)
int maxbytes = source.m_disasmintf->max_opcode_bytes();
// ensure that the PC is aligned to the minimum opcode size
- pc &= ~memory_byte_to_address_end(source.m_space, minbytes - 1);
+ pc &= ~source.m_space->byte_to_address_end(minbytes - 1);
// set the width of the third column according to display mode
if (m_right_column == DASM_RIGHTCOL_RAW || m_right_column == DASM_RIGHTCOL_ENCRYPTED)
@@ -390,7 +390,7 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines)
for (int line = 0; line < lines; line++)
{
// convert PC to a byte offset
- offs_t pcbyte = memory_address_to_byte(source.m_space, pc) & source.m_space->logbytemask;
+ offs_t pcbyte = source.m_space->address_to_byte(pc) & source.m_space->logbytemask();
// save a copy of the previous line as a backup if we're only doing one line
int instr = startline + line;
@@ -401,7 +401,7 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines)
// convert back and set the address of this instruction
m_byteaddress[instr] = pcbyte;
- sprintf(&destbuf[0], " %s ", core_i64_hex_format(memory_byte_to_address(source.m_space, pcbyte), source.m_space->logaddrchars));
+ sprintf(&destbuf[0], " %s ", core_i64_hex_format(source.m_space->byte_to_address(pcbyte), source.m_space->logaddrchars()));
// make sure we can translate the address, and then disassemble the result
char buffer[100];
@@ -419,7 +419,7 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines)
}
// disassemble the result
- pc += numbytes = source.m_disasmintf->disassemble(buffer, pc & source.m_space->logaddrmask, opbuf, argbuf) & DASMFLAG_LENGTHMASK;
+ pc += numbytes = source.m_disasmintf->disassemble(buffer, pc & source.m_space->logaddrmask(), opbuf, argbuf) & DASMFLAG_LENGTHMASK;
}
else
strcpy(buffer, "<unmapped>");
@@ -431,13 +431,13 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines)
if (m_right_column == DASM_RIGHTCOL_RAW || m_right_column == DASM_RIGHTCOL_ENCRYPTED)
{
// get the bytes
- numbytes = memory_address_to_byte(source.m_space, numbytes) & source.m_space->logbytemask;
+ numbytes = source.m_space->address_to_byte(numbytes) & source.m_space->logbytemask();
generate_bytes(pcbyte, numbytes, minbytes, &destbuf[m_divider2], m_allocated.x - m_divider2, m_right_column == DASM_RIGHTCOL_ENCRYPTED);
}
else if (m_right_column == DASM_RIGHTCOL_COMMENTS)
{
// get and add the comment, if present
- offs_t comment_address = memory_byte_to_address(source.m_space, m_byteaddress[instr]);
+ offs_t comment_address = source.m_space->byte_to_address(m_byteaddress[instr]);
const char *text = debug_comment_get_text(&source.m_device, comment_address, debug_comment_get_opcode_crc32(&source.m_device, comment_address));
if (text != NULL)
sprintf(&destbuf[m_divider2], "// %.*s", m_allocated.x - m_divider2 - 1, text);
@@ -449,8 +449,8 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines)
}
// update opcode base information
- m_last_direct_decrypted = source.m_space->direct.decrypted;
- m_last_direct_raw = source.m_space->direct.raw;
+ m_last_direct_decrypted = source.m_space->direct().decrypted();
+ m_last_direct_raw = source.m_space->direct().raw();
m_last_change_count = debug_comment_all_change_count(&m_machine);
// now longer need to recompute
@@ -469,7 +469,7 @@ void debug_view_disasm::view_update()
const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);
offs_t pc = cpu_get_pc(&source.m_device);
- offs_t pcbyte = memory_address_to_byte(source.m_space, pc) & source.m_space->logbytemask;
+ offs_t pcbyte = source.m_space->address_to_byte(pc) & source.m_space->logbytemask();
// update our context; if the expression is dirty, recompute
if (m_expression.dirty())
@@ -480,7 +480,7 @@ void debug_view_disasm::view_update()
UINT64 result = m_expression.value();
if (result != previous)
{
- offs_t resultbyte = memory_address_to_byte(source.m_space, result) & source.m_space->logbytemask;
+ offs_t resultbyte = source.m_space->address_to_byte(result) & source.m_space->logbytemask();
// see if the new result is an address we already have
UINT32 row;
@@ -498,7 +498,7 @@ void debug_view_disasm::view_update()
}
// if the opcode base has changed, rework things
- if (source.m_space->direct.decrypted != m_last_direct_decrypted || source.m_space->direct.raw != m_last_direct_raw)
+ if (source.m_space->direct().decrypted() != m_last_direct_decrypted || source.m_space->direct().raw() != m_last_direct_raw)
m_recompute = true;
// if the comments have changed, redo it
@@ -517,7 +517,7 @@ recompute:
m_topleft.x = 0;
// recompute from where we last recomputed!
- recompute(memory_byte_to_address(source.m_space, m_byteaddress[0]), 0, m_total.y);
+ recompute(source.m_space->byte_to_address(m_byteaddress[0]), 0, m_total.y);
}
else
{
@@ -579,7 +579,7 @@ recompute:
else
{
for (device_debug::breakpoint *bp = source.m_device.debug()->breakpoint_first(); bp != NULL; bp = bp->next())
- if (m_byteaddress[effrow] == (memory_address_to_byte(source.m_space, bp->address()) & source.m_space->logbytemask))
+ if (m_byteaddress[effrow] == (source.m_space->address_to_byte(bp->address()) & source.m_space->logbytemask()))
attrib = DCA_CHANGED;
}
@@ -627,7 +627,7 @@ recompute:
offs_t debug_view_disasm::selected_address()
{
flush_updates();
- return memory_byte_to_address(downcast<const debug_view_disasm_source &>(*m_source).m_space, m_byteaddress[m_cursor.y]);
+ return downcast<const debug_view_disasm_source &>(*m_source).m_space->byte_to_address(m_byteaddress[m_cursor.y]);
}
@@ -695,7 +695,7 @@ void debug_view_disasm::set_disasm_width(UINT32 width)
void debug_view_disasm::set_selected_address(offs_t address)
{
const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);
- offs_t byteaddress = memory_address_to_byte(source.m_space, address) & source.m_space->logbytemask;
+ offs_t byteaddress = source.m_space->address_to_byte(address) & source.m_space->logbytemask();
for (int line = 0; line < m_total.y; line++)
if (m_byteaddress[line] == byteaddress)
{
diff --git a/src/emu/debug/dvmemory.c b/src/emu/debug/dvmemory.c
index 652c98bbb6f..4399565929e 100644
--- a/src/emu/debug/dvmemory.c
+++ b/src/emu/debug/dvmemory.c
@@ -79,8 +79,8 @@ debug_view_memory_source::debug_view_memory_source(const char *name, const addre
m_base(NULL),
m_length(0),
m_offsetxor(0),
- m_endianness(space.endianness),
- m_prefsize(space.dbits / 8)
+ m_endianness(space.endianness()),
+ m_prefsize(space.data_width() / 8)
{
}
@@ -159,7 +159,7 @@ void debug_view_memory::enumerate_sources()
const address_space *space = memintf->space(spacenum);
if (space != NULL)
{
- name.printf("%s '%s' %s space memory", memintf->device().name(), memintf->device().tag(), space->name);
+ name.printf("%s '%s' %s space memory", memintf->device().name(), memintf->device().tag(), space->name());
m_source_list.append(*auto_alloc(&m_machine, debug_view_memory_source(name, *space)));
}
}
@@ -263,7 +263,7 @@ void debug_view_memory::view_update()
if (effrow < m_total.y)
{
offs_t addrbyte = m_byte_offset + effrow * m_bytes_per_row;
- offs_t address = (source.m_space != NULL) ? memory_byte_to_address(source.m_space, addrbyte) : addrbyte;
+ offs_t address = (source.m_space != NULL) ? source.m_space->byte_to_address(addrbyte) : addrbyte;
char addrtext[20];
// generate the address
@@ -441,8 +441,8 @@ void debug_view_memory::recompute()
int addrchars;
if (source.m_space != NULL)
{
- m_maxaddr = m_no_translation ? source.m_space->bytemask : source.m_space->logbytemask;
- addrchars = m_no_translation ? source.m_space->addrchars : source.m_space->logaddrchars;
+ m_maxaddr = m_no_translation ? source.m_space->bytemask() : source.m_space->logbytemask();
+ addrchars = m_no_translation ? source.m_space->addrchars() : source.m_space->logaddrchars();
}
else
{
@@ -457,9 +457,9 @@ void debug_view_memory::recompute()
m_addrformat.printf("%%0%dX%*s", addrchars, 8 - addrchars, "");
// if we are viewing a space with a minimum chunk size, clamp the bytes per chunk
- if (source.m_space != NULL && source.m_space->ashift < 0)
+ if (source.m_space != NULL && source.m_space->byte_to_address(1) > 1)
{
- UINT32 min_bytes_per_chunk = 1 << -source.m_space->ashift;
+ UINT32 min_bytes_per_chunk = source.m_space->byte_to_address(1);
while (m_bytes_per_chunk < min_bytes_per_chunk)
{
m_bytes_per_chunk *= 2;
@@ -521,7 +521,7 @@ bool debug_view_memory::needs_recompute()
const debug_view_memory_source &source = downcast<const debug_view_memory_source &>(*m_source);
offs_t resultbyte;
if (source.m_space != NULL)
- resultbyte = memory_address_to_byte(source.m_space, m_expression.value()) & source.m_space->logbytemask;
+ resultbyte = source.m_space->address_to_byte(m_expression.value()) & source.m_space->logbytemask();
else
resultbyte = m_expression.value();
@@ -621,7 +621,7 @@ bool debug_view_memory::read(UINT8 size, offs_t offs, UINT64 &data)
{
offs_t dummyaddr = offs;
- bool ismapped = m_no_translation ? true : source.m_memintf->translate(source.m_space->spacenum, TRANSLATE_READ_DEBUG, dummyaddr);
+ bool ismapped = m_no_translation ? true : source.m_memintf->translate(source.m_space->spacenum(), TRANSLATE_READ_DEBUG, dummyaddr);
data = ~(UINT64)0;
if (ismapped)
{
diff --git a/src/emu/delegate.c b/src/emu/delegate.c
new file mode 100644
index 00000000000..aafb8143714
--- /dev/null
+++ b/src/emu/delegate.c
@@ -0,0 +1,97 @@
+/***************************************************************************
+
+ delegate.c
+
+ Templates and classes to enable delegates for callbacks.
+
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+***************************************************************************/
+
+#include "emucore.h"
+#include "delegate.h"
+
+
+//**************************************************************************
+// BINDABLE OBJECT
+//**************************************************************************
+
+//-------------------------------------------------
+// bindable_object - constructor
+//-------------------------------------------------
+
+bindable_object::bindable_object()
+{
+}
+
+
+//-------------------------------------------------
+// ~bindable_object - destructor
+//-------------------------------------------------
+
+bindable_object::~bindable_object()
+{
+}
+
+
+
+//**************************************************************************
+// INTERNAL DELEGATE HELPERS
+//**************************************************************************
+
+#if (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL)
+
+// NULL structure used in dummy constructor
+delegate_gcc_mfp_internal delegate_gcc_mfp_null;
+
+
+//-------------------------------------------------
+// delegate_convert_raw - given an object and
+// an raw function, adjust the object base and
+// return the actual final code pointer
+//-------------------------------------------------
+
+delegate_generic_function delegate_convert_raw(delegate_generic_class *&object, delegate_gcc_mfp_internal &mfp)
+{
+ // apply the "this" delta to the object first
+ object = reinterpret_cast<delegate_generic_class *>(reinterpret_cast<UINT8 *>(object) + mfp.this_delta);
+
+ // if the low bit of the vtable index is clear, then it is just a raw function pointer
+ if (!(mfp.u.vtable_index & 1))
+ return mfp.u.funcptr;
+
+ // otherwise, it is the byte index into the vtable where the actual function lives
+ UINT8 *vtable_base = *reinterpret_cast<UINT8 **>(object);
+ return *reinterpret_cast<delegate_generic_function *>(vtable_base + mfp.u.vtable_index - 1);
+}
+
+#endif
diff --git a/src/emu/delegate.h b/src/emu/delegate.h
new file mode 100644
index 00000000000..e4e418524de
--- /dev/null
+++ b/src/emu/delegate.h
@@ -0,0 +1,1209 @@
+/***************************************************************************
+
+ delegate.h
+
+ Templates and classes to enable delegates for callbacks.
+
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+****************************************************************************
+
+ There are many implementations of delegate-like functionality for
+ C++ code, but none of them is a perfect drop-in fit for use in MAME.
+ In order to be useful in MAME, we need the following properties:
+
+ * No significant overhead; we want to use these for memory
+ accessors, and memory accessor overhead is already the dominant
+ performance aspect for most drivers.
+
+ * Existing static functions need to be bound with an additional
+ pointer parameter as the first argument. All existing
+ implementations that allow static function binding assume the
+ same signature as the member functions.
+
+ * We must be able to bind the function separately from the
+ object. This is to allow configurations to bind functions
+ before the objects are created.
+
+ Thus, the implementations below are based on existing works but are
+ really a new implementation that is specific to MAME.
+
+ --------------------------------------------------------------------
+
+ The "compatible" version of delegates is based on an implementation
+ from Sergey Ryazanov, found here:
+
+ http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx
+
+ These delegates essentially generate a templated static stub function
+ for each target function. The static function takes the first
+ parameter, uses it as the object pointer, and calls through the
+ member function. For static functions, the stub is compatible with
+ the signature of a static function, so we just set the stub directly.
+
+ Pros:
+ * should work with any modern compiler
+ * static bindings are just as fast as direct calls
+
+ Cons:
+ * lots of little stub functions generated
+ * double-hops on member function calls means more overhead
+ * calling through stub functions repackages parameters
+
+ --------------------------------------------------------------------
+
+ The "internal" version of delegates makes use of the internal
+ structure of member function pointers in order to convert them at
+ binding time into simple static function pointers. This only works
+ on platforms where object->func(p1, p2) is equivalent in calling
+ convention to func(object, p1, p2).
+
+ Most of the information on how this works comes from Don Clugston
+ in this article:
+
+ http://www.codeproject.com/KB/cpp/FastDelegate.aspx
+
+ Pros:
+ * as fast as a standard function call in static and member cases
+ * no stub functions or double-hops needed
+
+ Cons:
+ * requires internal knowledge of the member function pointer
+ * only works for GCC (for now; MSVC info is also readily available)
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __DELEGATE_H__
+#define __DELEGATE_H__
+
+
+//**************************************************************************
+// MACROS
+//**************************************************************************
+
+// types of delegates supported
+#define DELEGATE_TYPE_COMPATIBLE 0
+#define DELEGATE_TYPE_INTERNAL 1
+
+// select which one we will be using
+#if defined(__GNUC__)
+#define USE_DELEGATE_TYPE DELEGATE_TYPE_INTERNAL
+#else
+#define USE_DELEGATE_TYPE DELEGATE_TYPE_COMPATIBLE
+#endif
+
+// nicer macros to hide the template gobblety-gook and to pass the names
+#define bind_member_name(_class, _member, _name) _bind_member<_class, &_class::_member>(_name)
+#define bind_member(_class, _member) bind_member_name(_class, _member, #_class "::" #_member)
+#define bind_static(_class, _func) _bind_static<_class, &_func>(#_func)
+
+
+
+//**************************************************************************
+// HELPER CLASSES
+//**************************************************************************
+
+// ======================> generic_class
+
+// define a dummy generic class that is just straight single-inheritance
+#ifdef _MSC_VER
+class __single_inheritance generic_class;
+class delegate_generic_class { };
+#else
+class delegate_generic_class;
+#endif
+
+
+// ======================> bindable_object
+
+// define a bindable_object base class that must be at the root of any object
+// hierarchy which intends to do late binding
+class bindable_object
+{
+public:
+ // virtual destructor to ensure this is a polymorphic class
+ bindable_object();
+ virtual ~bindable_object();
+};
+
+// define a deferred cast helper function that does a proper dynamic_cast
+// from a bindable_object to the target class, and returns a delegate_generic_class
+template<class _TargetClass>
+static delegate_generic_class *deferred_cast(bindable_object &object)
+{
+ return reinterpret_cast<delegate_generic_class *>(dynamic_cast<_TargetClass *>(&object));
+}
+
+// we store pointers to these deferred casting helpers, so make a friendly type for it
+typedef delegate_generic_class *(*deferred_cast_func)(bindable_object &object);
+
+
+// ======================> delegate_base
+
+// simple base class for all delegates to derive from; it is explicitly
+// polymorphic so that a delegate_base * can be used as a lowest-common
+// denominator, and then downcast to the appropriate type with proper
+// type checking
+class delegate_base
+{
+public:
+ delegate_base(deferred_cast_func caster, const char *name)
+ : m_caster(caster),
+ m_name(name) { }
+
+ virtual ~delegate_base() { }
+
+ // getters
+ bool isnull() const { return (m_caster == NULL); }
+ bool valid_target(bindable_object &object) const { return ((*m_caster)(object) != NULL); }
+ const char *name() const { return m_name; }
+
+protected:
+ deferred_cast_func m_caster; // pointer to helper function that does the cast
+ const char * m_name; // name string
+};
+
+
+
+//**************************************************************************
+// COMPATIBLE DELEGATES
+//**************************************************************************
+
+#if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE)
+
+// ======================> proto_delegate_0param
+
+template<typename _ReturnType>
+class proto_delegate_0param : public delegate_base
+{
+protected:
+ // pointer to a static version of the function which takes the object as a first parameter
+ typedef _ReturnType (*static_func)(delegate_generic_class *);
+
+public:
+ // constructors
+ proto_delegate_0param(static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
+ : delegate_base(caster, name),
+ m_function(function) { }
+
+ proto_delegate_0param(const proto_delegate_0param &proto)
+ : delegate_base(proto.m_caster, proto.m_name),
+ m_function(proto.m_function) { }
+
+ // create a member function proto-delegate
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)()>
+ static proto_delegate_0param _create_member(const char *name = NULL)
+ {
+ return proto_delegate_0param(&method_stub<_FunctionClass, _FunctionPtr>, &deferred_cast<_FunctionClass>, name);
+ }
+
+ // create a static function proto-delegate
+ template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *)>
+ static proto_delegate_0param _create_static(const char *name = NULL)
+ {
+ return proto_delegate_0param(reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
+ }
+
+ // equality testing
+ bool operator==(const proto_delegate_0param &rhs) const
+ {
+ return (m_function == rhs.m_function && m_caster == rhs.m_caster);
+ }
+
+protected:
+ // helper stub that calls the member function
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)()>
+ static _ReturnType method_stub(delegate_generic_class *object_ptr)
+ {
+ _FunctionClass *p = reinterpret_cast<_FunctionClass *>(object_ptr);
+ return (p->*_FunctionPtr)();
+ }
+
+ // internal state
+ static_func m_function; // pointer to the stub or static function
+};
+
+
+// ======================> delegate_0param
+
+template<typename _ReturnType>
+class delegate_0param : public proto_delegate_0param<_ReturnType>
+{
+ typedef proto_delegate_0param<_ReturnType> proto_base;
+
+ using delegate_base::m_caster;
+ using proto_base::m_function;
+
+public:
+ // constructors
+ delegate_0param()
+ : m_object(NULL) { }
+
+ delegate_0param(proto_base proto)
+ : proto_delegate_0param<_ReturnType>(proto),
+ m_object(NULL) { }
+
+ delegate_0param(proto_base proto, bindable_object &object)
+ : proto_delegate_0param<_ReturnType>(proto),
+ m_object((*m_caster)(object)) { }
+
+ // bind the actual object
+ void bind(bindable_object &object) { m_object = (*m_caster)(object); }
+
+ // call the function
+ _ReturnType operator()() const { return (*m_function)(m_object); }
+
+ // testing
+ bool has_object() const { return (m_object != NULL); }
+ bool operator==(const delegate_0param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
+
+protected:
+ // internal state
+ delegate_generic_class *m_object; // pointer to the post-cast object
+};
+
+
+// ======================> proto_delegate_1param
+
+template<typename _ReturnType, typename _P1Type>
+class proto_delegate_1param : public delegate_base
+{
+protected:
+ // pointer to a static version of the function which takes the object as a first parameter
+ typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type);
+
+public:
+ // constructors
+ proto_delegate_1param(static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
+ : delegate_base(caster, name),
+ m_function(function) { }
+
+ proto_delegate_1param(const proto_delegate_1param &proto)
+ : delegate_base(proto.m_caster, proto.m_name),
+ m_function(proto.m_function) { }
+
+ // create a member function proto-delegate
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type)>
+ static proto_delegate_1param _create_member(const char *name = NULL)
+ {
+ return proto_delegate_1param(&method_stub<_FunctionClass, _FunctionPtr>, &deferred_cast<_FunctionClass>, name);
+ }
+
+ // create a static function proto-delegate
+ template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type)>
+ static proto_delegate_1param _create_static(const char *name = NULL)
+ {
+ return proto_delegate_1param(reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
+ }
+
+ // equality testing
+ bool operator==(const proto_delegate_1param &rhs) const
+ {
+ return (m_function == rhs.m_function && m_caster == rhs.m_caster);
+ }
+
+protected:
+ // helper stub that calls the member function
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type)>
+ static _ReturnType method_stub(delegate_generic_class *object_ptr, _P1Type p1)
+ {
+ _FunctionClass *p = reinterpret_cast<_FunctionClass *>(object_ptr);
+ return (p->*_FunctionPtr)(p1);
+ }
+
+ // internal state
+ static_func m_function; // pointer to the stub or static function
+};
+
+
+// ======================> delegate_1param
+
+template<typename _ReturnType, typename _P1Type>
+class delegate_1param : public proto_delegate_1param<_ReturnType, _P1Type>
+{
+ typedef proto_delegate_1param<_ReturnType, _P1Type> proto_base;
+
+ using delegate_base::m_caster;
+ using proto_base::m_function;
+
+public:
+ // constructors
+ delegate_1param()
+ : m_object(NULL) { }
+
+ delegate_1param(proto_delegate_1param<_ReturnType, _P1Type> proto)
+ : proto_delegate_1param<_ReturnType, _P1Type>(proto),
+ m_object(NULL) { }
+
+ delegate_1param(proto_delegate_1param<_ReturnType, _P1Type> proto, bindable_object &object)
+ : proto_delegate_1param<_ReturnType, _P1Type>(proto),
+ m_object((*m_caster)(object)) { }
+
+ // bind the actual object
+ void bind(bindable_object &object) { m_object = (*m_caster)(object); }
+
+ // call the function
+ _ReturnType operator()(_P1Type p1) const { return (*m_function)(m_object, p1); }
+
+ // testing
+ bool has_object() const { return (m_object != NULL); }
+ bool operator==(const delegate_1param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
+
+protected:
+ // internal state
+ delegate_generic_class *m_object; // pointer to the post-cast object
+};
+
+
+// ======================> proto_delegate_2param
+
+template<typename _ReturnType, typename _P1Type, typename _P2Type>
+class proto_delegate_2param : public delegate_base
+{
+protected:
+ // pointer to a static version of the function which takes the object as a first parameter
+ typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type);
+
+public:
+ // constructors
+ proto_delegate_2param(static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
+ : delegate_base(caster, name),
+ m_function(function) { }
+
+ proto_delegate_2param(const proto_delegate_2param &proto)
+ : delegate_base(proto.m_caster, proto.m_name),
+ m_function(proto.m_function) { }
+
+ // create a member function proto-delegate
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type)>
+ static proto_delegate_2param _create_member(const char *name = NULL)
+ {
+ return proto_delegate_2param(&method_stub<_FunctionClass, _FunctionPtr>, &deferred_cast<_FunctionClass>, name);
+ }
+
+ // create a static function proto-delegate
+ template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type, _P2Type)>
+ static proto_delegate_2param _create_static(const char *name = NULL)
+ {
+ return proto_delegate_2param(reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
+ }
+
+ // equality testing
+ bool operator==(const proto_delegate_2param &rhs) const
+ {
+ return (m_function == rhs.m_function && m_caster == rhs.m_caster);
+ }
+
+protected:
+ // helper stub that calls the member function
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type)>
+ static _ReturnType method_stub(delegate_generic_class *object_ptr, _P1Type p1, _P2Type p2)
+ {
+ _FunctionClass *p = reinterpret_cast<_FunctionClass *>(object_ptr);
+ return (p->*_FunctionPtr)(p1, p2);
+ }
+
+ // internal state
+ static_func m_function; // pointer to the stub or static function
+};
+
+
+// ======================> delegate_2param
+
+template<typename _ReturnType, typename _P1Type, typename _P2Type>
+class delegate_2param : public proto_delegate_2param<_ReturnType, _P1Type, _P2Type>
+{
+ typedef proto_delegate_2param<_ReturnType, _P1Type, _P2Type> proto_base;
+
+ using delegate_base::m_caster;
+ using proto_base::m_function;
+
+public:
+ // constructors
+ delegate_2param()
+ : m_object(NULL) { }
+
+ delegate_2param(proto_delegate_2param<_ReturnType, _P1Type, _P2Type> proto)
+ : proto_delegate_2param<_ReturnType, _P1Type, _P2Type>(proto),
+ m_object(NULL) { }
+
+ delegate_2param(proto_delegate_2param<_ReturnType, _P1Type, _P2Type> proto, bindable_object &object)
+ : proto_delegate_2param<_ReturnType, _P1Type, _P2Type>(proto),
+ m_object((*m_caster)(object)) { }
+
+ // bind the actual object
+ void bind(bindable_object &object) { m_object = (*m_caster)(object); }
+
+ // call the function
+ _ReturnType operator()(_P1Type p1, _P2Type p2) const { return (*m_function)(m_object, p1, p2); }
+
+ // testing
+ bool has_object() const { return (m_object != NULL); }
+ bool operator==(const delegate_2param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
+
+protected:
+ // internal state
+ delegate_generic_class *m_object; // pointer to the post-cast object
+};
+
+
+// ======================> proto_delegate_3param
+
+template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type>
+class proto_delegate_3param : public delegate_base
+{
+protected:
+ // pointer to a static version of the function which takes the object as a first parameter
+ typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type, _P3Type);
+
+public:
+ // constructors
+ proto_delegate_3param(static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
+ : delegate_base(caster, name),
+ m_function(function) { }
+
+ proto_delegate_3param(const proto_delegate_3param &proto)
+ : delegate_base(proto.m_caster, proto.m_name),
+ m_function(proto.m_function) { }
+
+ // create a member function proto-delegate
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type, _P3Type)>
+ static proto_delegate_3param _create_member(const char *name = NULL)
+ {
+ return proto_delegate_3param(&method_stub<_FunctionClass, _FunctionPtr>, &deferred_cast<_FunctionClass>, name);
+ }
+
+ // create a static function proto-delegate
+ template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type, _P2Type, _P3Type)>
+ static proto_delegate_3param _create_static(const char *name = NULL)
+ {
+ return proto_delegate_3param(reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
+ }
+
+ // equality testing
+ bool operator==(const proto_delegate_3param &rhs) const
+ {
+ return (m_function == rhs.m_function && m_caster == rhs.m_caster);
+ }
+
+protected:
+ // helper stub that calls the member function
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type, _P3Type)>
+ static _ReturnType method_stub(delegate_generic_class *object_ptr, _P1Type p1, _P2Type p2, _P3Type p3)
+ {
+ _FunctionClass *p = reinterpret_cast<_FunctionClass *>(object_ptr);
+ return (p->*_FunctionPtr)(p1, p2, p3);
+ }
+
+ // internal state
+ static_func m_function; // pointer to the stub or static function
+};
+
+
+// ======================> delegate_3param
+
+template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type>
+class delegate_3param : public proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type>
+{
+ typedef proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type> proto_base;
+
+ using delegate_base::m_caster;
+ using proto_base::m_function;
+
+public:
+ // constructors
+ delegate_3param()
+ : m_object(NULL) { }
+
+ delegate_3param(proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type> proto)
+ : proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type>(proto),
+ m_object(NULL) { }
+
+ delegate_3param(proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type> proto, bindable_object &object)
+ : proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type>(proto),
+ m_object((*m_caster)(object)) { }
+
+ // bind the actual object
+ void bind(bindable_object &object) { m_object = (*m_caster)(object); }
+
+ // call the function
+ _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3) const { return (*m_function)(m_object, p1, p2, p3); }
+
+ // testing
+ bool has_object() const { return (m_object != NULL); }
+ bool operator==(const delegate_3param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
+
+protected:
+ // internal state
+ delegate_generic_class *m_object; // pointer to the post-cast object
+};
+
+
+// ======================> proto_delegate_4param
+
+template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type>
+class proto_delegate_4param : public delegate_base
+{
+protected:
+ // pointer to a static version of the function which takes the object as a first parameter
+ typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type, _P3Type, _P4Type);
+
+public:
+ // constructors
+ proto_delegate_4param(static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
+ : delegate_base(caster, name),
+ m_function(function) { }
+
+ proto_delegate_4param(const proto_delegate_4param &proto)
+ : delegate_base(proto.m_caster, proto.m_name),
+ m_function(proto.m_function) { }
+
+ // create a member function proto-delegate
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type, _P3Type, _P4Type)>
+ static proto_delegate_4param _create_member(const char *name = NULL)
+ {
+ return proto_delegate_4param(&method_stub<_FunctionClass, _FunctionPtr>, &deferred_cast<_FunctionClass>, name);
+ }
+
+ // create a static function proto-delegate
+ template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type, _P2Type, _P3Type, _P4Type)>
+ static proto_delegate_4param _create_static(const char *name = NULL)
+ {
+ return proto_delegate_4param(reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
+ }
+
+ // equality testing
+ bool operator==(const proto_delegate_4param &rhs) const
+ {
+ return (m_function == rhs.m_function && m_caster == rhs.m_caster);
+ }
+
+protected:
+ // helper stub that calls the member function
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type, _P3Type, _P4Type)>
+ static _ReturnType method_stub(delegate_generic_class *object_ptr, _P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4)
+ {
+ _FunctionClass *p = reinterpret_cast<_FunctionClass *>(object_ptr);
+ return (p->*_FunctionPtr)(p1, p2, p3, p4);
+ }
+
+ // internal state
+ static_func m_function; // pointer to the stub or static function
+};
+
+
+// ======================> delegate_4param
+
+template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type>
+class delegate_4param : public proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type>
+{
+ typedef proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type> proto_base;
+
+ using delegate_base::m_caster;
+ using proto_base::m_function;
+
+public:
+ // constructors
+ delegate_4param()
+ : m_object(NULL) { }
+
+ delegate_4param(proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type> proto)
+ : proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type>(proto),
+ m_object(NULL) { }
+
+ delegate_4param(proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type> proto, bindable_object &object)
+ : proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type>(proto),
+ m_object((*m_caster)(object)) { }
+
+ // bind the actual object
+ void bind(bindable_object &object) { m_object = (*m_caster)(object); }
+
+ // call the function
+ _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4) const { return (*m_function)(m_object, p1, p2, p3, p4); }
+
+ // testing
+ bool has_object() const { return (m_object != NULL); }
+ bool operator==(const delegate_4param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
+
+protected:
+ // internal state
+ delegate_generic_class *m_object; // pointer to the post-cast object
+};
+
+
+#endif
+
+
+//**************************************************************************
+// GCC DELEGATES
+//**************************************************************************
+
+#if (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL)
+
+// a generic function pointer type and a generic member function pointer type
+typedef void (*delegate_generic_function)();
+
+// struct describing the contents of a member function pointer
+struct delegate_gcc_mfp_internal
+{
+ union // first item can be one of two things:
+ {
+ delegate_generic_function funcptr; // if even, it's a pointer to the function
+ FPTR vtable_index; // if odd, it's the byte offset into the vtable
+ } u;
+ int this_delta; // delta to apply to the 'this' pointer
+};
+
+// helper function
+delegate_generic_function delegate_convert_raw(delegate_generic_class *&object, delegate_gcc_mfp_internal &mfp);
+
+// global dummy extern
+extern delegate_gcc_mfp_internal delegate_gcc_mfp_null;
+
+
+// ======================> proto_delegate_0param
+
+template<typename _ReturnType>
+class proto_delegate_0param : public delegate_base
+{
+protected:
+ // pointer to a static function which takes the object as a first parameter
+ typedef _ReturnType (*static_func)(delegate_generic_class *);
+
+public:
+ // constructors
+ proto_delegate_0param(delegate_gcc_mfp_internal &mfp = delegate_gcc_mfp_null, static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
+ : delegate_base(caster, name),
+ m_function(function),
+ m_rawfunction(mfp) { }
+
+ proto_delegate_0param(const proto_delegate_0param &proto)
+ : delegate_base(proto.m_caster, proto.m_name),
+ m_function(proto.m_function),
+ m_rawfunction(proto.m_rawfunction) { }
+
+ // create a member function proto-delegate
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)()>
+ static proto_delegate_0param _create_member(const char *name = NULL)
+ {
+ union
+ {
+ _ReturnType (_FunctionClass::*mfp)();
+ delegate_gcc_mfp_internal internal;
+ } tempunion;
+ tempunion.mfp = _FunctionPtr;
+ return proto_delegate_0param(tempunion.internal, NULL, &deferred_cast<_FunctionClass>, name);
+ }
+
+ // create a static function proto-delegate
+ template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *)>
+ static proto_delegate_0param _create_static(const char *name = NULL)
+ {
+ return proto_delegate_0param(delegate_gcc_mfp_null, reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
+ }
+
+ // equality testing
+ bool operator==(const proto_delegate_0param &rhs) const
+ {
+ return (m_function == rhs.m_function && m_caster == rhs.m_caster &&
+ m_rawfunction.u.funcptr == rhs.m_rawfunction.u.funcptr &&
+ m_rawfunction.this_delta == rhs.m_rawfunction.this_delta);
+ }
+
+protected:
+ // internal state
+ static_func m_function; // generic static function pointer
+ delegate_gcc_mfp_internal m_rawfunction; // raw member function definition
+};
+
+
+// ======================> delegate_0param
+
+template<typename _ReturnType>
+class delegate_0param : public proto_delegate_0param<_ReturnType>
+{
+ typedef _ReturnType (*static_func)(delegate_generic_class *);
+ typedef proto_delegate_0param<_ReturnType> proto_base;
+
+ using delegate_base::m_caster;
+ using proto_base::m_function;
+ using proto_base::m_rawfunction;
+
+public:
+ // constructors
+ delegate_0param()
+ : m_object(NULL) { }
+
+ delegate_0param(proto_base proto)
+ : proto_delegate_0param<_ReturnType>(proto),
+ m_object(NULL) { }
+
+ delegate_0param(proto_base proto, bindable_object &object)
+ : proto_delegate_0param<_ReturnType>(proto),
+ m_object(NULL) { bind(object); }
+
+ // bind the actual object
+ void bind(bindable_object &object)
+ {
+ m_object = (*m_caster)(object);
+ if (m_rawfunction.u.funcptr != NULL)
+ m_function = reinterpret_cast<static_func>(delegate_convert_raw(m_object, m_rawfunction));
+ }
+
+ // call the function
+ _ReturnType operator()() const { return (*m_function)(m_object); }
+
+ // testing
+ bool has_object() const { return (m_object != NULL); }
+ bool operator==(const delegate_0param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
+
+protected:
+ // internal state
+ delegate_generic_class *m_object; // pointer to the post-cast object
+};
+
+
+// ======================> proto_delegate_1param
+
+template<typename _ReturnType, typename _P1Type>
+class proto_delegate_1param : public delegate_base
+{
+protected:
+ // pointer to a static function which takes the object as a first parameter
+ typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type);
+
+public:
+ // constructors
+ proto_delegate_1param(delegate_gcc_mfp_internal &mfp = delegate_gcc_mfp_null, static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
+ : delegate_base(caster, name),
+ m_function(function),
+ m_rawfunction(mfp) { }
+
+ proto_delegate_1param(const proto_delegate_1param &proto)
+ : delegate_base(proto.m_caster, proto.m_name),
+ m_function(proto.m_function),
+ m_rawfunction(proto.m_rawfunction) { }
+
+ // create a member function proto-delegate
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type)>
+ static proto_delegate_1param _create_member(const char *name = NULL)
+ {
+ union
+ {
+ _ReturnType (_FunctionClass::*mfp)(_P1Type);
+ delegate_gcc_mfp_internal internal;
+ } tempunion;
+ tempunion.mfp = _FunctionPtr;
+ return proto_delegate_1param(tempunion.internal, NULL, &deferred_cast<_FunctionClass>, name);
+ }
+
+ // create a static function proto-delegate
+ template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type)>
+ static proto_delegate_1param _create_static(const char *name = NULL)
+ {
+ return proto_delegate_1param(delegate_gcc_mfp_null, reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
+ }
+
+ // equality testing
+ bool operator==(const proto_delegate_1param &rhs) const
+ {
+ return (m_function == rhs.m_function && m_caster == rhs.m_caster &&
+ m_rawfunction.u.funcptr == rhs.m_rawfunction.u.funcptr &&
+ m_rawfunction.this_delta == rhs.m_rawfunction.this_delta);
+ }
+
+protected:
+ // internal state
+ static_func m_function; // generic static function pointer
+ delegate_gcc_mfp_internal m_rawfunction; // raw member function definition
+};
+
+
+// ======================> delegate_1param
+
+template<typename _ReturnType, typename _P1Type>
+class delegate_1param : public proto_delegate_1param<_ReturnType, _P1Type>
+{
+ typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type);
+ typedef proto_delegate_1param<_ReturnType, _P1Type> proto_base;
+
+ using delegate_base::m_caster;
+ using proto_base::m_function;
+ using proto_base::m_rawfunction;
+
+public:
+ // constructors
+ delegate_1param()
+ : m_object(NULL) { }
+
+ delegate_1param(proto_base proto)
+ : proto_delegate_1param<_ReturnType, _P1Type>(proto),
+ m_object(NULL) { }
+
+ delegate_1param(proto_base proto, bindable_object &object)
+ : proto_delegate_1param<_ReturnType, _P1Type>(proto),
+ m_object(NULL) { bind(object); }
+
+ // bind the actual object
+ void bind(bindable_object &object)
+ {
+ m_object = (*m_caster)(object);
+ if (m_rawfunction.u.funcptr != NULL)
+ m_function = reinterpret_cast<static_func>(delegate_convert_raw(m_object, m_rawfunction));
+ }
+
+ // call the function
+ _ReturnType operator()(_P1Type p1) const { return (*m_function)(m_object, p1); }
+
+ // testing
+ bool has_object() const { return (m_object != NULL); }
+ bool operator==(const delegate_1param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
+
+protected:
+ // internal state
+ delegate_generic_class *m_object; // pointer to the post-cast object
+};
+
+
+// ======================> proto_delegate_2param
+
+template<typename _ReturnType, typename _P1Type, typename _P2Type>
+class proto_delegate_2param : public delegate_base
+{
+protected:
+ // pointer to a static function which takes the object as a first parameter
+ typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type);
+
+public:
+ // constructors
+ proto_delegate_2param(delegate_gcc_mfp_internal &mfp = delegate_gcc_mfp_null, static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
+ : delegate_base(caster, name),
+ m_function(function),
+ m_rawfunction(mfp) { }
+
+ proto_delegate_2param(const proto_delegate_2param &proto)
+ : delegate_base(proto.m_caster, proto.m_name),
+ m_function(proto.m_function),
+ m_rawfunction(proto.m_rawfunction) { }
+
+ // create a member function proto-delegate
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type)>
+ static proto_delegate_2param _create_member(const char *name = NULL)
+ {
+ union
+ {
+ _ReturnType (_FunctionClass::*mfp)(_P1Type, _P2Type);
+ delegate_gcc_mfp_internal internal;
+ } tempunion;
+ tempunion.mfp = _FunctionPtr;
+ return proto_delegate_2param(tempunion.internal, NULL, &deferred_cast<_FunctionClass>, name);
+ }
+
+ // create a static function proto-delegate
+ template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type, _P2Type)>
+ static proto_delegate_2param _create_static(const char *name = NULL)
+ {
+ return proto_delegate_2param(delegate_gcc_mfp_null, reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
+ }
+
+ // equality testing
+ bool operator==(const proto_delegate_2param &rhs) const
+ {
+ return (m_function == rhs.m_function && m_caster == rhs.m_caster &&
+ m_rawfunction.u.funcptr == rhs.m_rawfunction.u.funcptr &&
+ m_rawfunction.this_delta == rhs.m_rawfunction.this_delta);
+ }
+
+protected:
+ // internal state
+ static_func m_function; // generic static function pointer
+ delegate_gcc_mfp_internal m_rawfunction; // raw member function definition
+};
+
+
+// ======================> delegate_2param
+
+template<typename _ReturnType, typename _P1Type, typename _P2Type>
+class delegate_2param : public proto_delegate_2param<_ReturnType, _P1Type, _P2Type>
+{
+ typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type);
+ typedef proto_delegate_2param<_ReturnType, _P1Type, _P2Type> proto_base;
+
+ using delegate_base::m_caster;
+ using proto_base::m_function;
+ using proto_base::m_rawfunction;
+
+public:
+ // constructors
+ delegate_2param()
+ : m_object(NULL) { }
+
+ delegate_2param(proto_base proto)
+ : proto_delegate_2param<_ReturnType, _P1Type, _P2Type>(proto),
+ m_object(NULL) { }
+
+ delegate_2param(proto_base proto, bindable_object &object)
+ : proto_delegate_2param<_ReturnType, _P1Type, _P2Type>(proto),
+ m_object(NULL) { bind(object); }
+
+ // bind the actual object
+ void bind(bindable_object &object)
+ {
+ m_object = (*m_caster)(object);
+ if (m_rawfunction.u.funcptr != NULL)
+ m_function = reinterpret_cast<static_func>(delegate_convert_raw(m_object, m_rawfunction));
+ }
+
+ // call the function
+ _ReturnType operator()(_P1Type p1, _P2Type p2) const { return (*m_function)(m_object, p1, p2); }
+
+ // testing
+ bool has_object() const { return (m_object != NULL); }
+ bool operator==(const delegate_2param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
+
+protected:
+ // internal state
+ delegate_generic_class *m_object; // pointer to the post-cast object
+};
+
+
+// ======================> proto_delegate_3param
+
+template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type>
+class proto_delegate_3param : public delegate_base
+{
+protected:
+ // pointer to a static function which takes the object as a first parameter
+ typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type, _P3Type);
+
+public:
+ // constructors
+ proto_delegate_3param(delegate_gcc_mfp_internal &mfp = delegate_gcc_mfp_null, static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
+ : delegate_base(caster, name),
+ m_function(function),
+ m_rawfunction(mfp) { }
+
+ proto_delegate_3param(const proto_delegate_3param &proto)
+ : delegate_base(proto.m_caster, proto.m_name),
+ m_function(proto.m_function),
+ m_rawfunction(proto.m_rawfunction) { }
+
+ // create a member function proto-delegate
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type, _P3Type)>
+ static proto_delegate_3param _create_member(const char *name = NULL)
+ {
+ union
+ {
+ _ReturnType (_FunctionClass::*mfp)(_P1Type, _P2Type, _P3Type);
+ delegate_gcc_mfp_internal internal;
+ } tempunion;
+ tempunion.mfp = _FunctionPtr;
+ return proto_delegate_3param(tempunion.internal, NULL, &deferred_cast<_FunctionClass>, name);
+ }
+
+ // create a static function proto-delegate
+ template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type, _P2Type, _P3Type)>
+ static proto_delegate_3param _create_static(const char *name = NULL)
+ {
+ return proto_delegate_3param(delegate_gcc_mfp_null, reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
+ }
+
+ // equality testing
+ bool operator==(const proto_delegate_3param &rhs) const
+ {
+ return (m_function == rhs.m_function && m_caster == rhs.m_caster &&
+ m_rawfunction.u.funcptr == rhs.m_rawfunction.u.funcptr &&
+ m_rawfunction.this_delta == rhs.m_rawfunction.this_delta);
+ }
+
+protected:
+ // internal state
+ static_func m_function; // generic static function pointer
+ delegate_gcc_mfp_internal m_rawfunction; // raw member function definition
+};
+
+
+// ======================> delegate_3param
+
+template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type>
+class delegate_3param : public proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type>
+{
+ typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type, _P3Type);
+ typedef proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type> proto_base;
+
+ using delegate_base::m_caster;
+ using proto_base::m_function;
+ using proto_base::m_rawfunction;
+
+public:
+ // constructors
+ delegate_3param()
+ : m_object(NULL) { }
+
+ delegate_3param(proto_base proto)
+ : proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type>(proto),
+ m_object(NULL) { }
+
+ delegate_3param(proto_base proto, bindable_object &object)
+ : proto_delegate_3param<_ReturnType, _P1Type, _P2Type, _P3Type>(proto),
+ m_object(NULL) { bind(object); }
+
+ // bind the actual object
+ void bind(bindable_object &object)
+ {
+ m_object = (*m_caster)(object);
+ if (m_rawfunction.u.funcptr != NULL)
+ m_function = reinterpret_cast<static_func>(delegate_convert_raw(m_object, m_rawfunction));
+ }
+
+ // call the function
+ _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3) const { return (*m_function)(m_object, p1, p2, p3); }
+
+ // testing
+ bool has_object() const { return (m_object != NULL); }
+ bool operator==(const delegate_3param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
+
+protected:
+ // internal state
+ delegate_generic_class *m_object; // pointer to the post-cast object
+};
+
+
+// ======================> proto_delegate_4param
+
+template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type>
+class proto_delegate_4param : public delegate_base
+{
+protected:
+ // pointer to a static function which takes the object as a first parameter
+ typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type, _P3Type, _P4Type);
+
+public:
+ // constructors
+ proto_delegate_4param(delegate_gcc_mfp_internal &mfp = delegate_gcc_mfp_null, static_func function = NULL, deferred_cast_func caster = NULL, const char *name = NULL)
+ : delegate_base(caster, name),
+ m_function(function),
+ m_rawfunction(mfp) { }
+
+ proto_delegate_4param(const proto_delegate_4param &proto)
+ : delegate_base(proto.m_caster, proto.m_name),
+ m_function(proto.m_function),
+ m_rawfunction(proto.m_rawfunction) { }
+
+ // create a member function proto-delegate
+ template<class _FunctionClass, _ReturnType (_FunctionClass::*_FunctionPtr)(_P1Type, _P2Type, _P3Type, _P4Type)>
+ static proto_delegate_4param _create_member(const char *name = NULL)
+ {
+ union
+ {
+ _ReturnType (_FunctionClass::*mfp)(_P1Type, _P2Type, _P3Type, _P4Type);
+ delegate_gcc_mfp_internal internal;
+ } tempunion;
+ tempunion.mfp = _FunctionPtr;
+ return proto_delegate_4param(tempunion.internal, NULL, &deferred_cast<_FunctionClass>, name);
+ }
+
+ // create a static function proto-delegate
+ template<class _FunctionClass, _ReturnType (*_FunctionPtr)(_FunctionClass *, _P1Type, _P2Type, _P3Type, _P4Type)>
+ static proto_delegate_4param _create_static(const char *name = NULL)
+ {
+ return proto_delegate_4param(delegate_gcc_mfp_null, reinterpret_cast<static_func>(_FunctionPtr), &deferred_cast<_FunctionClass>, name);
+ }
+
+ // equality testing
+ bool operator==(const proto_delegate_4param &rhs) const
+ {
+ return (m_function == rhs.m_function && m_caster == rhs.m_caster &&
+ m_rawfunction.u.funcptr == rhs.m_rawfunction.u.funcptr &&
+ m_rawfunction.this_delta == rhs.m_rawfunction.this_delta);
+ }
+
+protected:
+ // internal state
+ static_func m_function; // generic static function pointer
+ delegate_gcc_mfp_internal m_rawfunction; // raw member function definition
+};
+
+
+// ======================> delegate_4param
+
+template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type>
+class delegate_4param : public proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type>
+{
+ typedef _ReturnType (*static_func)(delegate_generic_class *, _P1Type, _P2Type, _P3Type, _P4Type);
+ typedef proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type> proto_base;
+
+ using delegate_base::m_caster;
+ using proto_base::m_function;
+ using proto_base::m_rawfunction;
+
+public:
+ // constructors
+ delegate_4param()
+ : m_object(NULL) { }
+
+ delegate_4param(proto_base proto)
+ : proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type>(proto),
+ m_object(NULL) { }
+
+ delegate_4param(proto_base proto, bindable_object &object)
+ : proto_delegate_4param<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type>(proto),
+ m_object(NULL) { bind(object); }
+
+ // bind the actual object
+ void bind(bindable_object &object)
+ {
+ m_object = (*m_caster)(object);
+ if (m_rawfunction.u.funcptr != NULL)
+ m_function = reinterpret_cast<static_func>(delegate_convert_raw(m_object, m_rawfunction));
+ }
+
+ // call the function
+ _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4) const { return (*m_function)(m_object, p1, p2, p3, p4); }
+
+ // testing
+ bool has_object() const { return (m_object != NULL); }
+ bool operator==(const delegate_4param &rhs) const { return (m_object == rhs.m_object && proto_base::operator==(rhs)); }
+
+protected:
+ // internal state
+ delegate_generic_class *m_object; // pointer to the post-cast object
+};
+
+
+
+#endif
+
+
+#endif /* __DELEGATE_H__ */
diff --git a/src/emu/devcpu.c b/src/emu/devcpu.c
index 44f297b9444..1ce1716af62 100644
--- a/src/emu/devcpu.c
+++ b/src/emu/devcpu.c
@@ -78,6 +78,8 @@ legacy_cpu_device_config::legacy_cpu_device_config(const machine_config &mconfig
m_space_config[spacenum].m_addrbus_width = get_legacy_config_int(DEVINFO_INT_ADDRBUS_WIDTH + spacenum);
m_space_config[spacenum].m_addrbus_shift = get_legacy_config_int(DEVINFO_INT_ADDRBUS_SHIFT + spacenum);
m_space_config[spacenum].m_logaddr_width = get_legacy_config_int(CPUINFO_INT_LOGADDR_WIDTH + spacenum);
+ if (m_space_config[spacenum].m_logaddr_width == 0)
+ m_space_config[spacenum].m_logaddr_width = m_space_config[spacenum].m_addrbus_width;
m_space_config[spacenum].m_page_shift = get_legacy_config_int(CPUINFO_INT_PAGE_SHIFT + spacenum);
m_space_config[spacenum].m_internal_map = reinterpret_cast<address_map_constructor>(get_legacy_config_fct(DEVINFO_PTR_INTERNAL_MEMORY_MAP + spacenum));
m_space_config[spacenum].m_default_map = reinterpret_cast<address_map_constructor>(get_legacy_config_fct(DEVINFO_PTR_DEFAULT_MEMORY_MAP + spacenum));
diff --git a/src/emu/devintrf.h b/src/emu/devintrf.h
index bd5dc450708..03f8c812d7b 100644
--- a/src/emu/devintrf.h
+++ b/src/emu/devintrf.h
@@ -347,7 +347,7 @@ protected:
// ======================> device_t
// device_t represents a device that is live and attached to a running_machine
-class device_t
+class device_t : public bindable_object
{
DISABLE_COPYING(device_t);
diff --git a/src/emu/dimemory.c b/src/emu/dimemory.c
index 06d5ab879d1..79d22a81a0b 100644
--- a/src/emu/dimemory.c
+++ b/src/emu/dimemory.c
@@ -191,7 +191,7 @@ bool device_config_memory_interface::interface_validity_check(const game_driver
::address_map *map = global_alloc(::address_map(*devconfig, spacenum));
// if this is an empty map, just skip it
- if (map->m_entrylist == NULL)
+ if (map->m_entrylist.first() == NULL)
{
global_free(map);
continue;
@@ -210,7 +210,7 @@ bool device_config_memory_interface::interface_validity_check(const game_driver
}
// loop over entries and look for errors
- for (address_map_entry *entry = map->m_entrylist; entry != NULL; entry = entry->m_next)
+ for (address_map_entry *entry = map->m_entrylist.first(); entry != NULL; entry = entry->next())
{
UINT32 bytestart = spaceconfig->addr2byte(entry->m_addrstart);
UINT32 byteend = spaceconfig->addr2byte_end(entry->m_addrend);
@@ -219,12 +219,12 @@ bool device_config_memory_interface::interface_validity_check(const game_driver
if (!detected_overlap)
{
address_map_entry *scan;
- for (scan = map->m_entrylist; scan != entry; scan = scan->m_next)
+ for (scan = map->m_entrylist.first(); scan != entry; scan = scan->next())
if (entry->m_addrstart <= scan->m_addrend && entry->m_addrend >= scan->m_addrstart &&
- ((entry->m_read.type != AMH_NONE && scan->m_read.type != AMH_NONE) ||
- (entry->m_write.type != AMH_NONE && scan->m_write.type != AMH_NONE)))
+ ((entry->m_read.m_type != AMH_NONE && scan->m_read.m_type != AMH_NONE) ||
+ (entry->m_write.m_type != AMH_NONE && scan->m_write.m_type != AMH_NONE)))
{
- mame_printf_warning("%s: %s '%s' %s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", driver.source_file, driver.name, devconfig->tag(), spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_read.type, entry->m_write.type, scan->m_addrstart, scan->m_addrend, scan->m_read.type, scan->m_write.type);
+ mame_printf_warning("%s: %s '%s' %s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", driver.source_file, driver.name, devconfig->tag(), spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_read.m_type, entry->m_write.m_type, scan->m_addrstart, scan->m_addrend, scan->m_read.m_type, scan->m_write.m_type);
detected_overlap = true;
break;
}
@@ -245,7 +245,7 @@ bool device_config_memory_interface::interface_validity_check(const game_driver
}
// if this is a program space, auto-assign implicit ROM entries
- if (entry->m_read.type == AMH_ROM && entry->m_region == NULL)
+ if (entry->m_read.m_type == AMH_ROM && entry->m_region == NULL)
{
entry->m_region = devconfig->tag();
entry->m_rgnoffs = entry->m_addrstart;
@@ -287,25 +287,25 @@ bool device_config_memory_interface::interface_validity_check(const game_driver
}
// make sure all devices exist
- if ((entry->m_read.type == AMH_DEVICE_HANDLER && entry->m_read.tag != NULL && m_machine_config.m_devicelist.find(entry->m_read.tag) == NULL) ||
- (entry->m_write.type == AMH_DEVICE_HANDLER && entry->m_write.tag != NULL && m_machine_config.m_devicelist.find(entry->m_write.tag) == NULL))
+ if ((entry->m_read.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_read.m_tag != NULL && m_machine_config.m_devicelist.find(entry->m_read.m_tag) == NULL) ||
+ (entry->m_write.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_write.m_tag != NULL && m_machine_config.m_devicelist.find(entry->m_write.m_tag) == NULL))
{
- mame_printf_error("%s: %s device '%s' %s space memory map entry references nonexistant device '%s'\n", driver.source_file, driver.name, devconfig->tag(), spaceconfig->m_name, entry->m_write.tag);
+ mame_printf_error("%s: %s device '%s' %s space memory map entry references nonexistant device '%s'\n", driver.source_file, driver.name, devconfig->tag(), spaceconfig->m_name, entry->m_write.m_tag);
error = true;
}
// make sure ports exist
-// if ((entry->m_read.type == AMH_PORT && entry->m_read.tag != NULL && portlist.find(entry->m_read.tag) == NULL) ||
-// (entry->m_write.type == AMH_PORT && entry->m_write.tag != NULL && portlist.find(entry->m_write.tag) == NULL))
+// if ((entry->m_read.m_type == AMH_PORT && entry->m_read.m_tag != NULL && portlist.find(entry->m_read.m_tag) == NULL) ||
+// (entry->m_write.m_type == AMH_PORT && entry->m_write.m_tag != NULL && portlist.find(entry->m_write.m_tag) == NULL))
// {
// mame_printf_error("%s: %s device '%s' %s space memory map entry references nonexistant port tag '%s'\n", driver.source_file, driver.name, devconfig->tag(), spaceconfig->m_name, entry->m_read.tag);
// error = true;
// }
// validate bank and share tags
- if (entry->m_read.type == AMH_BANK && !validate_tag(&driver, "bank", entry->m_read.tag))
+ if (entry->m_read.m_type == AMH_BANK && !validate_tag(&driver, "bank", entry->m_read.m_tag))
error = true ;
- if (entry->m_write.type == AMH_BANK && !validate_tag(&driver, "bank", entry->m_write.tag))
+ if (entry->m_write.m_type == AMH_BANK && !validate_tag(&driver, "bank", entry->m_write.m_tag))
error = true;
if (entry->m_share != NULL && !validate_tag(&driver, "share", entry->m_share))
error = true;
@@ -350,10 +350,10 @@ device_memory_interface::~device_memory_interface()
// to a device
//-------------------------------------------------
-void device_memory_interface::set_address_space(int spacenum, const address_space *space)
+void device_memory_interface::set_address_space(int spacenum, address_space &space)
{
assert(spacenum < ARRAY_LENGTH(m_addrspace));
- m_addrspace[spacenum] = space;
+ m_addrspace[spacenum] = &space;
}
diff --git a/src/emu/dimemory.h b/src/emu/dimemory.h
index 633f4def973..fd3ab38cc44 100644
--- a/src/emu/dimemory.h
+++ b/src/emu/dimemory.h
@@ -100,48 +100,6 @@ const int TRANSLATE_FETCH_DEBUG = (TRANSLATE_FETCH | TRANSLATE_DEBUG_MASK);
// TYPE DEFINITIONS
//**************************************************************************
-// ======================> address_space_config
-
-class address_space_config
-{
-public:
- address_space_config();
- address_space_config(const char *name, endianness_t endian, UINT8 datawidth, UINT8 addrwidth, INT8 addrshift = 0, address_map_constructor internal = NULL, address_map_constructor defmap = NULL);
- address_space_config(const char *name, endianness_t endian, UINT8 datawidth, UINT8 addrwidth, INT8 addrshift, UINT8 logwidth, UINT8 pageshift, address_map_constructor internal = NULL, address_map_constructor defmap = NULL);
-
- inline offs_t addr2byte(offs_t address) const
- {
- return (m_addrbus_shift < 0) ? (address << -m_addrbus_shift) : (address >> m_addrbus_shift);
- }
-
- inline offs_t addr2byte_end(offs_t address) const
- {
- return (m_addrbus_shift < 0) ? ((address << -m_addrbus_shift) | ((1 << -m_addrbus_shift) - 1)) : (address >> m_addrbus_shift);
- }
-
- inline offs_t byte2addr(offs_t address) const
- {
- return (m_addrbus_shift > 0) ? (address << m_addrbus_shift) : (address >> -m_addrbus_shift);
- }
-
- inline offs_t byte2addr_end(offs_t address) const
- {
- return (m_addrbus_shift > 0) ? ((address << m_addrbus_shift) | ((1 << -m_addrbus_shift) - 1)) : (address >> -m_addrbus_shift);
- }
-
- const char * m_name;
- endianness_t m_endianness;
- UINT8 m_databus_width;
- UINT8 m_addrbus_width;
- INT8 m_addrbus_shift;
- UINT8 m_logaddr_width;
- UINT8 m_page_shift;
- address_map_constructor m_internal_map;
- address_map_constructor m_default_map;
-};
-
-
-
// ======================> device_config_memory_interface
// class representing interface-specific configuration state
@@ -187,11 +145,11 @@ public:
// basic information getters
const address_space_config *space_config(int spacenum = 0) const { return m_memory_config.space_config(spacenum); }
- const address_space *space(int index = 0) const { return m_addrspace[index]; }
- const address_space *space(device_space index) const { return m_addrspace[static_cast<int>(index)]; }
+ address_space *space(int index = 0) const { return m_addrspace[index]; }
+ address_space *space(device_space index) const { return m_addrspace[static_cast<int>(index)]; }
// address space accessors
- void set_address_space(int spacenum, const address_space *space);
+ void set_address_space(int spacenum, address_space &space);
// address translation
bool translate(int spacenum, int intention, offs_t &address) { return memory_translate(spacenum, intention, address); }
@@ -212,7 +170,7 @@ protected:
// configuration
const device_config_memory_interface &m_memory_config; // reference to our device_config_execute_interface
- const address_space * m_addrspace[ADDRESS_SPACES]; // reported address spaces
+ address_space * m_addrspace[ADDRESS_SPACES]; // reported address spaces
};
diff --git a/src/emu/emu.h b/src/emu/emu.h
index f9f2da32672..6caa97d20ec 100644
--- a/src/emu/emu.h
+++ b/src/emu/emu.h
@@ -62,6 +62,7 @@
#include "attotime.h"
#include "fileio.h" // remove me once NVRAM is implemented as device
#include "tokenize.h"
+#include "delegate.h"
// memory and address spaces
#include "memory.h"
diff --git a/src/emu/emu.mak b/src/emu/emu.mak
index 6dba0ca0f36..8f585948bc4 100644
--- a/src/emu/emu.mak
+++ b/src/emu/emu.mak
@@ -45,6 +45,7 @@ EMUOBJS = \
$(EMUOBJ)/config.o \
$(EMUOBJ)/crsshair.o \
$(EMUOBJ)/debugger.o \
+ $(EMUOBJ)/delegate.o \
$(EMUOBJ)/devcb.o \
$(EMUOBJ)/devcpu.o \
$(EMUOBJ)/devimage.o \
diff --git a/src/emu/emucore.h b/src/emu/emucore.h
index 23cebabd16c..e8063ca859e 100644
--- a/src/emu/emucore.h
+++ b/src/emu/emucore.h
@@ -355,6 +355,100 @@ inline _Dest crosscast(_Source *src)
// COMMON TEMPLATES
//**************************************************************************
+// ======================> simple_list
+
+template<class T>
+class simple_list
+{
+ DISABLE_COPYING(simple_list);
+
+ T *m_head;
+ T *m_tail;
+ resource_pool &m_pool;
+ int m_count;
+
+public:
+ simple_list(resource_pool &pool = global_resource_pool) :
+ m_head(NULL),
+ m_tail(NULL),
+ m_pool(pool),
+ m_count(0) { }
+
+ virtual ~simple_list() { reset(); }
+
+ T *first() const { return m_head; }
+ T *last() const { return m_tail; }
+ int count() const { return m_count; }
+
+ void reset() { while (m_head != NULL) remove(*m_head); }
+
+ int index(T *object) const
+ {
+ int num = 0;
+ for (T *cur = m_head; cur != NULL; cur = cur->m_next)
+ if (cur == object)
+ return num;
+ else
+ num++;
+ return -1;
+ }
+
+ T &prepend(T &object)
+ {
+ object.m_next = m_head;
+ m_head = &object;
+ if (m_tail == NULL)
+ m_tail = m_head;
+ m_count++;
+ return object;
+ }
+
+ T &append(T &object)
+ {
+ object.m_next = NULL;
+ if (m_tail != NULL)
+ m_tail = m_tail->m_next = &object;
+ else
+ m_tail = m_head = &object;
+ m_count++;
+ return object;
+ }
+
+ void detach(T &object)
+ {
+ T *prev = NULL;
+ for (T *cur = m_head; cur != NULL; prev = cur, cur = cur->m_next)
+ if (cur == &object)
+ {
+ if (prev != NULL)
+ prev->m_next = object.m_next;
+ else
+ m_head = object.m_next;
+ if (m_tail == &object)
+ m_tail = prev;
+ m_count--;
+ return;
+ }
+ }
+
+ void remove(T &object)
+ {
+ detach(object);
+ pool_free(m_pool, &object);
+ }
+
+ T *find(int index) const
+ {
+ for (T *cur = m_head; cur != NULL; cur = cur->m_next)
+ if (index-- == 0)
+ return cur;
+ return NULL;
+ }
+};
+
+
+// ======================> tagged_list
+
template<class T>
class tagged_list
{
diff --git a/src/emu/machine.c b/src/emu/machine.c
index 9cabef0fe6d..8313e204dc9 100644
--- a/src/emu/machine.c
+++ b/src/emu/machine.c
@@ -243,7 +243,7 @@ const char *running_machine::describe_context()
{
cpu_device *cpu = downcast<cpu_device *>(&executing->device());
if (cpu != NULL)
- m_context.printf("'%s' (%s)", cpu->tag(), core_i64_hex_format(cpu->pc(), cpu->space(AS_PROGRAM)->logaddrchars));
+ m_context.printf("'%s' (%s)", cpu->tag(), core_i64_hex_format(cpu->pc(), cpu->space(AS_PROGRAM)->logaddrchars()));
else
m_context.printf("'%s'", cpu->tag());
}
diff --git a/src/emu/machine.h b/src/emu/machine.h
index bd03b754b6c..3f672bd8166 100644
--- a/src/emu/machine.h
+++ b/src/emu/machine.h
@@ -158,7 +158,7 @@ typedef tagged_list<region_info> region_list;
// base class for all driver data structures
-class driver_data_t
+class driver_data_t : public bindable_object
{
public:
driver_data_t(running_machine &machine);
@@ -271,7 +271,7 @@ public:
// description of the currently-running machine
-class running_machine
+class running_machine : public bindable_object
{
DISABLE_COPYING(running_machine);
@@ -346,6 +346,7 @@ public:
// CPU information
cpu_device * firstcpu; // first CPU (allows for quick iteration via typenext)
+ address_space * m_nonspecific_space;// a dummy address_space used for legacy compatibility
// game-related information
const game_driver * gamedrv; // points to the definition of the game machine
diff --git a/src/emu/machine/generic.c b/src/emu/machine/generic.c
index b61f2bd0dcb..8bcb2ea00ff 100644
--- a/src/emu/machine/generic.c
+++ b/src/emu/machine/generic.c
@@ -816,7 +816,7 @@ INTERRUPT_GEN( irq7_line_assert ) { if (interrupt_enabled(device)) cpu_set_input
-------------------------------------------------*/
WRITE8_HANDLER( watchdog_reset_w ) { watchdog_reset(space->machine); }
-READ8_HANDLER( watchdog_reset_r ) { watchdog_reset(space->machine); return space->unmap; }
+READ8_HANDLER( watchdog_reset_r ) { watchdog_reset(space->machine); return space->unmap(); }
/*-------------------------------------------------
@@ -824,7 +824,7 @@ READ8_HANDLER( watchdog_reset_r ) { watchdog_reset(space->machine); return space
-------------------------------------------------*/
WRITE16_HANDLER( watchdog_reset16_w ) { watchdog_reset(space->machine); }
-READ16_HANDLER( watchdog_reset16_r ) { watchdog_reset(space->machine); return space->unmap; }
+READ16_HANDLER( watchdog_reset16_r ) { watchdog_reset(space->machine); return space->unmap(); }
/*-------------------------------------------------
@@ -832,7 +832,7 @@ READ16_HANDLER( watchdog_reset16_r ) { watchdog_reset(space->machine); return sp
-------------------------------------------------*/
WRITE32_HANDLER( watchdog_reset32_w ) { watchdog_reset(space->machine); }
-READ32_HANDLER( watchdog_reset32_r ) { watchdog_reset(space->machine); return space->unmap; }
+READ32_HANDLER( watchdog_reset32_r ) { watchdog_reset(space->machine); return space->unmap(); }
diff --git a/src/emu/machine/idectrl.c b/src/emu/machine/idectrl.c
index 9f443c31189..83f83b8f75f 100644
--- a/src/emu/machine/idectrl.c
+++ b/src/emu/machine/idectrl.c
@@ -1819,7 +1819,7 @@ static DEVICE_START( ide_controller )
ide->dma_space = memory->space(config->bmspace);
if (ide->dma_space == NULL)
throw emu_fatalerror("IDE controller '%s' bus master target '%s' does not have specified space %d!", device->tag(), config->bmcpu, config->bmspace);
- ide->dma_address_xor = (ide->dma_space->endianness == ENDIANNESS_LITTLE) ? 0 : 3;
+ ide->dma_address_xor = (ide->dma_space->endianness() == ENDIANNESS_LITTLE) ? 0 : 3;
}
/* get and copy the geometry */
diff --git a/src/emu/memory.c b/src/emu/memory.c
index 506c399f7f8..b1f3e6deada 100644
--- a/src/emu/memory.c
+++ b/src/emu/memory.c
@@ -4,8 +4,36 @@
Functions which handle device memory access.
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
****************************************************************************
@@ -177,2041 +205,2336 @@
#include "debug/debugcpu.h"
-/***************************************************************************
- DEBUGGING
-***************************************************************************/
+//**************************************************************************
+// DEBUGGING
+//**************************************************************************
#define MEM_DUMP (0)
#define VERBOSE (0)
-#define ALLOW_ONLY_AUTO_MALLOC_BANKS 0
#define VPRINTF(x) do { if (VERBOSE) mame_printf_debug x; } while (0)
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-/* banking constants */
-#define MAX_BANK_ENTRIES 4096 /* maximum number of possible bank values */
-
-/* address map lookup table definitions */
-#define LEVEL1_BITS 18 /* number of address bits in the level 1 table */
-#define LEVEL2_BITS (32 - LEVEL1_BITS) /* number of address bits in the level 2 table */
-#define SUBTABLE_COUNT 64 /* number of slots reserved for subtables */
-#define SUBTABLE_BASE (256 - SUBTABLE_COUNT) /* first index of a subtable */
-#define ENTRY_COUNT (SUBTABLE_BASE) /* number of legitimate (non-subtable) entries */
-#define SUBTABLE_ALLOC 8 /* number of subtables to allocate at a time */
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
-/* shares are initially mapped to this invalid pointer */
-#define UNMAPPED_SHARE_PTR ((void *)-1)
+// banking constants
+const int BANK_ENTRY_UNSPECIFIED = -1;
-/* other address map constants */
-#define MEMORY_BLOCK_CHUNK 65536 /* minimum chunk size of allocated memory blocks */
+// shares are initially mapped to this invalid pointer
+static void *UNMAPPED_SHARE_PTR = ((void *)-1);
-/* read or write constants */
-enum _read_or_write
-{
- ROW_READ,
- ROW_WRITE
-};
-typedef enum _read_or_write read_or_write;
+// other address map constants
+const int MEMORY_BLOCK_CHUNK = 65536; // minimum chunk size of allocated memory blocks
-/* static data access handler constants */
+// static data access handler constants
enum
{
- STATIC_INVALID = 0, /* invalid - should never be used */
- STATIC_BANK1 = 1, /* first memory bank */
- STATIC_BANKMAX = 122, /* last memory bank */
- STATIC_RAM, /* RAM - reads/writes map to dynamic banks */
- STATIC_ROM, /* ROM - reads = RAM; writes = UNMAP */
- STATIC_NOP, /* NOP - reads = unmapped value; writes = no-op */
- STATIC_UNMAP, /* unmapped - same as NOP except we log errors */
- STATIC_WATCHPOINT, /* watchpoint - used internally */
- STATIC_COUNT /* total number of static handlers */
+ STATIC_INVALID = 0, // invalid - should never be used
+ STATIC_BANK1 = 1, // first memory bank
+ STATIC_BANKMAX = 122, // last memory bank
+ STATIC_RAM, // RAM - reads/writes map to dynamic banks
+ STATIC_ROM, // ROM - reads = RAM; writes = UNMAP
+ STATIC_NOP, // NOP - reads = unmapped value; writes = no-op
+ STATIC_UNMAP, // unmapped - same as NOP except we log errors
+ STATIC_WATCHPOINT, // watchpoint - used internally
+ STATIC_COUNT // total number of static handlers
};
-/***************************************************************************
- MACROS
-***************************************************************************/
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
-/* table lookup helpers */
-#define LEVEL1_INDEX(a) ((a) >> LEVEL2_BITS)
-#define LEVEL2_INDEX(e,a) ((1 << LEVEL1_BITS) + (((e) - SUBTABLE_BASE) << LEVEL2_BITS) + ((a) & ((1 << LEVEL2_BITS) - 1)))
-/* helper macros */
-#define HANDLER_IS_RAM(h) ((FPTR)(h) == STATIC_RAM)
-#define HANDLER_IS_ROM(h) ((FPTR)(h) == STATIC_ROM)
-#define HANDLER_IS_BANK(h) ((FPTR)(h) >= STATIC_BANK1 && (FPTR)(h) <= STATIC_BANKMAX)
-#define HANDLER_IS_STATIC(h) ((FPTR)(h) < STATIC_COUNT)
+// ======================> memory_block
-#define HANDLER_TO_BANK(h) ((UINT32)(FPTR)(h))
+// a memory block is a chunk of RAM associated with a range of memory in a device's address space
+class memory_block
+{
+ DISABLE_COPYING(memory_block);
-#define SUBTABLE_PTR(tabledata, entry) (&(tabledata)->table[(1 << LEVEL1_BITS) + (((entry) - SUBTABLE_BASE) << LEVEL2_BITS)])
+ friend class simple_list<memory_block>;
+ friend resource_pool_object<memory_block>::~resource_pool_object();
+public:
+ // construction/destruction
+ memory_block(address_space &space, offs_t bytestart, offs_t byteend, void *memory = NULL);
+ ~memory_block();
+ // getters
+ memory_block *next() const { return m_next; }
+ offs_t bytestart() const { return m_bytestart; }
+ offs_t byteend() const { return m_byteend; }
+ UINT8 *data() const { return m_data; }
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
+ // is the given range contained by this memory block?
+ bool contains(address_space &space, offs_t bytestart, offs_t byteend) const
+ {
+ return (&space == &m_space && m_bytestart <= bytestart && m_byteend >= byteend);
+ }
-/* a memory block is a chunk of RAM associated with a range of memory in a device's address space */
-typedef struct _memory_block memory_block;
-struct _memory_block
-{
- memory_block * next; /* next memory block in the list */
- const address_space * space; /* which address space are we associated with? */
- UINT8 isallocated; /* did we allocate this ourselves? */
- offs_t bytestart, byteend; /* byte-normalized start/end for verifying a match */
- UINT8 * data; /* pointer to the data for this block */
+private:
+ // internal state
+ memory_block * m_next; // next memory block in the list
+ running_machine & m_machine; // need the machine to free our memory
+ address_space & m_space; // which address space are we associated with?
+ bool m_isallocated; // did we allocate this ourselves?
+ offs_t m_bytestart, m_byteend; // byte-normalized start/end for verifying a match
+ UINT8 * m_data; // pointer to the data for this block
};
-/* a bank reference is an entry in a list of address spaces that reference a given bank */
-typedef struct _bank_reference bank_reference;
-struct _bank_reference
+
+// ======================> memory_bank
+
+// a memory bank is a global pointer to memory that can be shared across devices and changed dynamically
+class memory_bank
{
- bank_reference * next; /* link to the next reference */
- const address_space * space; /* address space that references us */
-};
+ friend class simple_list<memory_bank>;
+ friend resource_pool_object<memory_bank>::~resource_pool_object();
+
+ // a bank reference is an entry in a list of address spaces that reference a given bank
+ class bank_reference
+ {
+ friend class simple_list<bank_reference>;
+ friend resource_pool_object<bank_reference>::~resource_pool_object();
+
+ public:
+ // construction/destruction
+ bank_reference(address_space &space, read_or_write readorwrite)
+ : m_next(NULL),
+ m_space(space),
+ m_readorwrite(readorwrite) { }
+
+ // getters
+ bank_reference *next() const { return m_next; }
+ address_space &space() const { return m_space; }
+
+ // does this reference match the space+read/write combination?
+ bool matches(address_space &space, read_or_write readorwrite) const
+ {
+ return (&space == &m_space && (readorwrite == ROW_READWRITE || readorwrite == m_readorwrite));
+ }
+
+ private:
+ // internal state
+ bank_reference * m_next; // link to the next reference
+ address_space & m_space; // address space that references us
+ read_or_write m_readorwrite; // used for read or write?
+ };
+
+ // a bank_entry contains a raw and decrypted pointer
+ struct bank_entry
+ {
+ UINT8 * m_raw;
+ UINT8 * m_decrypted;
+ };
-/* a bank is a global pointer to memory that can be shared across devices and changed dynamically */
-typedef struct _bank_info bank_info;
-struct _bank_info
-{
- bank_info * next; /* next bank in sequence */
- UINT8 index; /* array index for this handler */
- UINT8 read; /* is this bank used for reads? */
- UINT8 write; /* is this bank used for writes? */
- void * handler; /* handler for this bank */
- bank_reference * reflist; /* linked list of address spaces referencing this bank */
- offs_t bytestart; /* byte-adjusted start offset */
- offs_t byteend; /* byte-adjusted end offset */
- UINT16 curentry; /* current entry */
- void * entry[MAX_BANK_ENTRIES];/* array of entries for this bank */
- void * entryd[MAX_BANK_ENTRIES];/* array of decrypted entries for this bank */
- char * name; /* friendly name for this bank */
- char tag[1]; /* tag associated with this bank */
+public:
+ // construction/destruction
+ memory_bank(address_space &space, int index, offs_t bytestart, offs_t byteend, const char *tag = NULL);
+ ~memory_bank();
+
+ // getters
+ memory_bank *next() const { return m_next; }
+ int index() const { return m_index; }
+ int entry() const { return m_curentry; }
+ bool anonymous() const { return m_anonymous; }
+ offs_t bytestart() const { return m_bytestart; }
+ void *base() const { return *m_baseptr; }
+ void *base_decrypted() const { return *m_basedptr; }
+ const char *tag() const { return m_tag; }
+ const char *name() const { return m_name; }
+
+ // compare a range against our range
+ bool matches_exactly(offs_t bytestart, offs_t byteend) const { return (m_bytestart == bytestart && m_byteend == byteend); }
+ bool fully_covers(offs_t bytestart, offs_t byteend) const { return m_bytestart <= bytestart && m_byteend >= byteend; }
+ bool partially_covers(offs_t bytestart, offs_t byteend) const { return m_bytestart <= byteend && m_byteend >= bytestart; }
+
+ // track and verify address space references to this bank
+ bool references_space(address_space &space, read_or_write readorwrite) const;
+ void add_reference(address_space &space, read_or_write readorwrite);
+
+ // set the base explicitly
+ void set_base(void *base);
+ void set_base_decrypted(void *base);
+
+ // configure and set entries
+ void configure(int entrynum, void *base);
+ void configure_decrypted(int entrynum, void *base);
+ void set_entry(int entrynum);
+
+private:
+ // internal helpers
+ void invalidate_references();
+ void expand_entries(int entrynum);
+
+ // internal state
+ memory_bank * m_next; // next bank in sequence
+ running_machine & m_machine; // need the machine to free our memory
+ UINT8 ** m_baseptr; // pointer to our base pointer in the global array
+ UINT8 ** m_basedptr; // same for the decrypted base pointer
+ UINT8 m_index; // array index for this handler
+ bool m_anonymous; // are we anonymous or explicit?
+ offs_t m_bytestart; // byte-adjusted start offset
+ offs_t m_byteend; // byte-adjusted end offset
+ int m_curentry; // current entry
+ bank_entry * m_entry; // array of entries (dynamically allocated)
+ int m_entry_count; // number of allocated entries
+ astring m_name; // friendly name for this bank
+ astring m_tag; // tag for this bank
+ simple_list<bank_reference> m_reflist; // linked list of address spaces referencing this bank
};
-/* In memory.h: typedef struct _direct_range direct_range; */
-struct _direct_range
+
+// ======================> handler_entry
+
+// a handler entry contains information about a memory handler
+class handler_entry : public bindable_object
{
- direct_range * next; /* pointer to the next range in the list */
- offs_t bytestart; /* starting byte offset of the range */
- offs_t byteend; /* ending byte offset of the range */
-};
+ DISABLE_COPYING(handler_entry);
+
+protected:
+ // construction/destruction
+ handler_entry(UINT8 width, endianness_t endianness, UINT8 **rambaseptr);
+ virtual ~handler_entry();
+
+public:
+ // getters
+ bool populated() const { return m_populated; }
+ offs_t bytestart() const { return m_bytestart; }
+ offs_t byteend() const { return m_byteend; }
+ offs_t bytemask() const { return m_bytemask; }
+ virtual const char *name() const = 0;
+
+ // return offset within the range referenced by this handler
+ offs_t byteoffset(offs_t byteaddress) const { return (byteaddress - m_bytestart) & m_bytemask; }
+
+ // return a pointer to the backing RAM at the given offset
+ UINT8 *ramptr(offs_t offset = 0) const { return *m_rambaseptr + offset; }
+
+ // see if we are an exact match to the given parameters
+ bool matches_exactly(offs_t bytestart, offs_t byteend, offs_t bytemask) const
+ {
+ return (m_populated && m_bytestart == bytestart && m_byteend == byteend && m_bytemask == bytemask);
+ }
+
+ // get the start/end address with the given mirror
+ void mirrored_start_end(offs_t byteaddress, offs_t &start, offs_t &end) const
+ {
+ offs_t mirrorbits = (byteaddress - m_bytestart) & ~m_bytemask;
+ start = m_bytestart | mirrorbits;
+ end = m_byteend | mirrorbits;
+ }
-/* In memory.h: typedef struct _handler_data handler_data */
-struct _handler_data
-{
- memory_handler handler; /* function pointer for handler */
- void * object; /* object associated with the handler */
- const char * name; /* name of the handler */
- memory_handler subhandler; /* function pointer for subhandler */
- void * subobject; /* object associated with the subhandler */
- UINT8 subunits; /* number of subunits to access */
- UINT8 subshift[8]; /* shift amounts for up to 8 subunits */
- offs_t bytestart; /* byte-adjusted start address for handler */
- offs_t byteend; /* byte-adjusted end address for handler */
- offs_t bytemask; /* byte-adjusted mask against the final address */
- UINT8 ** bankbaseptr; /* pointer to the bank base */
+ // configure the handler addresses, and mark as populated
+ void configure(offs_t bytestart, offs_t byteend, offs_t bytemask)
+ {
+ m_populated = true;
+ m_bytestart = bytestart;
+ m_byteend = byteend;
+ m_bytemask = bytemask;
+ }
+
+ // apply a global mask
+ void apply_mask(offs_t bytemask) { m_bytemask &= bytemask; }
+
+protected:
+ // internal helpers
+ void configure_subunits(UINT64 handlermask, int handlerbits);
+
+ // internal state
+ bool m_populated; // populated?
+ UINT8 m_datawidth;
+ endianness_t m_endianness;
+ offs_t m_bytestart; // byte-adjusted start address for handler
+ offs_t m_byteend; // byte-adjusted end address for handler
+ offs_t m_bytemask; // byte-adjusted mask against the final address
+ UINT8 ** m_rambaseptr; // pointer to the bank base
+ UINT8 m_subunits; // for width stubs, the number of subunits
+ UINT8 m_subshift[8]; // for width stubs, the shift of each subunit
};
-/* In memory.h: typedef struct _subtable_data subtable_data; */
-struct _subtable_data
+
+// ======================> handler_entry_read
+
+// a read-access-specific extension of handler_entry
+class handler_entry_read : public handler_entry
{
- UINT8 checksum_valid; /* is the checksum valid */
- UINT32 checksum; /* checksum over all the bytes */
- UINT32 usecount; /* number of times this has been used */
+public:
+ // construction/destruction
+ handler_entry_read(UINT8 width, endianness_t endianness, UINT8 **rambaseptr)
+ : handler_entry(width, endianness, rambaseptr)
+ {
+ m_legacy_object.space = NULL;
+ m_legacy_handler.space8 = NULL;
+ }
+
+ // getters
+ virtual const char *name() const;
+
+ // configure delegate callbacks
+ void set_delegate(read8_delegate delegate, UINT64 mask = 0);
+ void set_delegate(read16_delegate delegate, UINT64 mask = 0);
+ void set_delegate(read32_delegate delegate, UINT64 mask = 0);
+ void set_delegate(read64_delegate delegate, UINT64 mask = 0);
+
+ // configure legacy address space functions
+ void set_legacy_func(const address_space &space, read8_space_func func, const char *name, UINT64 mask = 0);
+ void set_legacy_func(const address_space &space, read16_space_func func, const char *name, UINT64 mask = 0);
+ void set_legacy_func(const address_space &space, read32_space_func func, const char *name, UINT64 mask = 0);
+ void set_legacy_func(const address_space &space, read64_space_func func, const char *name, UINT64 mask = 0);
+
+ // configure legacy device functions
+ void set_legacy_func(device_t &device, read8_device_func func, const char *name, UINT64 mask = 0);
+ void set_legacy_func(device_t &device, read16_device_func func, const char *name, UINT64 mask = 0);
+ void set_legacy_func(device_t &device, read32_device_func func, const char *name, UINT64 mask = 0);
+ void set_legacy_func(device_t &device, read64_device_func func, const char *name, UINT64 mask = 0);
+
+ // configure I/O port access
+ void set_ioport(const input_port_config &ioport);
+
+ // read via the underlying delegates
+ UINT8 read8(address_space &space, offs_t offset, UINT8 mask) const { return m_read8(space, offset, mask); }
+ UINT16 read16(address_space &space, offs_t offset, UINT16 mask) const { return m_read16(space, offset, mask); }
+ UINT32 read32(address_space &space, offs_t offset, UINT32 mask) const { return m_read32(space, offset, mask); }
+ UINT64 read64(address_space &space, offs_t offset, UINT64 mask) const { return m_read64(space, offset, mask); }
+
+private:
+ // stubs for converting between address sizes
+ UINT16 read_stub_16_from_8(address_space &space, offs_t offset, UINT16 mask);
+ UINT32 read_stub_32_from_8(address_space &space, offs_t offset, UINT32 mask);
+ UINT64 read_stub_64_from_8(address_space &space, offs_t offset, UINT64 mask);
+ UINT32 read_stub_32_from_16(address_space &space, offs_t offset, UINT32 mask);
+ UINT64 read_stub_64_from_16(address_space &space, offs_t offset, UINT64 mask);
+ UINT64 read_stub_64_from_32(address_space &space, offs_t offset, UINT64 mask);
+
+ // stubs for calling legacy read handlers
+ UINT8 read_stub_legacy(address_space &space, offs_t offset, UINT8 mask);
+ UINT16 read_stub_legacy(address_space &space, offs_t offset, UINT16 mask);
+ UINT32 read_stub_legacy(address_space &space, offs_t offset, UINT32 mask);
+ UINT64 read_stub_legacy(address_space &space, offs_t offset, UINT64 mask);
+
+ // stubs for reading I/O ports
+ template<typename _UintType>
+ _UintType read_stub_ioport(address_space &space, offs_t offset, _UintType mask) { return input_port_read_direct(m_ioport); }
+
+ // internal state
+ read8_delegate m_read8;
+ read16_delegate m_read16;
+ read32_delegate m_read32;
+ read64_delegate m_read64;
+ const input_port_config * m_ioport;
+
+ // unions to hold legacy objects and callbacks
+ union
+ {
+ const address_space * space;
+ device_t * device;
+ } m_legacy_object;
+
+ union
+ {
+ read8_space_func space8;
+ read16_space_func space16;
+ read32_space_func space32;
+ read64_space_func space64;
+ read8_device_func device8;
+ read16_device_func device16;
+ read32_device_func device32;
+ read64_device_func device64;
+ } m_legacy_handler;
};
-struct _memory_private
+
+// ======================> handler_entry_write
+
+// a write-access-specific extension of handler_entry
+class handler_entry_write : public handler_entry
{
- UINT8 initialized; /* have we completed initialization? */
+public:
+ // construction/destruction
+ handler_entry_write(UINT8 width, endianness_t endianness, UINT8 **rambaseptr)
+ : handler_entry(width, endianness, rambaseptr)
+ {
+ m_legacy_object.space = NULL;
+ m_legacy_handler.space8 = NULL;
+ }
+
+ // getters
+ virtual const char *name() const;
+
+ // configure delegate callbacks
+ void set_delegate(write8_delegate delegate, UINT64 mask = 0);
+ void set_delegate(write16_delegate delegate, UINT64 mask = 0);
+ void set_delegate(write32_delegate delegate, UINT64 mask = 0);
+ void set_delegate(write64_delegate delegate, UINT64 mask = 0);
+
+ // configure legacy address space functions
+ void set_legacy_func(const address_space &space, write8_space_func func, const char *name, UINT64 mask = 0);
+ void set_legacy_func(const address_space &space, write16_space_func func, const char *name, UINT64 mask = 0);
+ void set_legacy_func(const address_space &space, write32_space_func func, const char *name, UINT64 mask = 0);
+ void set_legacy_func(const address_space &space, write64_space_func func, const char *name, UINT64 mask = 0);
+
+ // configure legacy device functions
+ void set_legacy_func(device_t &device, write8_device_func func, const char *name, UINT64 mask = 0);
+ void set_legacy_func(device_t &device, write16_device_func func, const char *name, UINT64 mask = 0);
+ void set_legacy_func(device_t &device, write32_device_func func, const char *name, UINT64 mask = 0);
+ void set_legacy_func(device_t &device, write64_device_func func, const char *name, UINT64 mask = 0);
+
+ // configure I/O port access
+ void set_ioport(const input_port_config &ioport);
+
+ // write via the underlying delegates
+ void write8(address_space &space, offs_t offset, UINT8 data, UINT8 mask) const { m_write8(space, offset, data, mask); }
+ void write16(address_space &space, offs_t offset, UINT16 data, UINT16 mask) const { m_write16(space, offset, data, mask); }
+ void write32(address_space &space, offs_t offset, UINT32 data, UINT32 mask) const { m_write32(space, offset, data, mask); }
+ void write64(address_space &space, offs_t offset, UINT64 data, UINT64 mask) const { m_write64(space, offset, data, mask); }
+
+private:
+ // stubs for converting between address sizes
+ void write_stub_16_from_8(address_space &space, offs_t offset, UINT16 data, UINT16 mask);
+ void write_stub_32_from_8(address_space &space, offs_t offset, UINT32 data, UINT32 mask);
+ void write_stub_64_from_8(address_space &space, offs_t offset, UINT64 data, UINT64 mask);
+ void write_stub_32_from_16(address_space &space, offs_t offset, UINT32 data, UINT32 mask);
+ void write_stub_64_from_16(address_space &space, offs_t offset, UINT64 data, UINT64 mask);
+ void write_stub_64_from_32(address_space &space, offs_t offset, UINT64 data, UINT64 mask);
+
+ // stubs for calling legacy write handlers
+ void write_stub_legacy(address_space &space, offs_t offset, UINT8 data, UINT8 mask);
+ void write_stub_legacy(address_space &space, offs_t offset, UINT16 data, UINT16 mask);
+ void write_stub_legacy(address_space &space, offs_t offset, UINT32 data, UINT32 mask);
+ void write_stub_legacy(address_space &space, offs_t offset, UINT64 data, UINT64 mask);
+
+ // stubs for writing I/O ports
+ template<typename _UintType>
+ void write_stub_ioport(address_space &space, offs_t offset, _UintType data, _UintType mask) { input_port_write_direct(m_ioport, data, mask); }
+
+ // internal state
+ write8_delegate m_write8;
+ write16_delegate m_write16;
+ write32_delegate m_write32;
+ write64_delegate m_write64;
+ const input_port_config * m_ioport;
+
+ // unions to hold legacy objects and callbacks
+ union
+ {
+ const address_space * space;
+ device_t * device;
+ } m_legacy_object;
- const address_space * spacelist; /* list of address spaces */
+ union
+ {
+ write8_space_func space8;
+ write16_space_func space16;
+ write32_space_func space32;
+ write64_space_func space64;
+ write8_device_func device8;
+ write16_device_func device16;
+ write32_device_func device32;
+ write64_device_func device64;
+ } m_legacy_handler;
+};
- UINT8 * bank_ptr[STATIC_COUNT]; /* array of bank pointers */
- UINT8 * bankd_ptr[STATIC_COUNT]; /* array of decrypted bank pointers */
- memory_block * memory_block_list; /* head of the list of memory blocks */
+// ======================> address_table
- tagmap_t<bank_info *> bankmap; /* map for fast bank lookups */
- bank_info * banklist; /* data gathered for each bank */
- UINT8 banknext; /* next bank to allocate */
+// address_table contains information about read/write accesses within an address space
+class address_table : public bindable_object
+{
+ // address map lookup table definitions
+ static const int LEVEL1_BITS = 18; // number of address bits in the level 1 table
+ static const int LEVEL2_BITS = 32 - LEVEL1_BITS; // number of address bits in the level 2 table
+ static const int SUBTABLE_COUNT = 64; // number of slots reserved for subtables
+ static const int SUBTABLE_BASE = 256 - SUBTABLE_COUNT; // first index of a subtable
+ static const int ENTRY_COUNT = SUBTABLE_BASE; // number of legitimate (non-subtable) entries
+ static const int SUBTABLE_ALLOC = 8; // number of subtables to allocate at a time
- tagmap_t<void *> sharemap; /* map for share lookups */
+ inline int level2_bits() const { return m_large ? LEVEL2_BITS : 0; }
- UINT8 * wptable; /* watchpoint-fill table */
-};
+public:
+ // construction/destruction
+ address_table(address_space &space, bool large);
+ ~address_table();
+
+ // getters
+ virtual handler_entry &handler(UINT32 index) const = 0;
+ bool watchpoints_enabled() const { return (m_live_lookup == s_watchpoint_table); }
+ // address lookups
+ UINT32 lookup_live(offs_t byteaddress) const { return m_large ? lookup_live_large(byteaddress) : lookup_live_small(byteaddress); }
+ UINT32 lookup_live_small(offs_t byteaddress) const { return m_live_lookup[byteaddress]; }
+ UINT32 lookup_live_large(offs_t byteaddress) const
+ {
+ UINT32 entry = m_live_lookup[level1_index_large(byteaddress)];
+ if (entry >= SUBTABLE_BASE)
+ entry = m_live_lookup[level2_index_large(entry, byteaddress)];
+ return entry;
+ }
-/***************************************************************************
- GLOBAL VARIABLES
-***************************************************************************/
+ UINT32 lookup(offs_t byteaddress) const
+ {
+ UINT32 entry = m_live_lookup[level1_index(byteaddress)];
+ if (entry >= SUBTABLE_BASE)
+ entry = m_live_lookup[level2_index(entry, byteaddress)];
+ return entry;
+ }
-#define ACCESSOR_GROUP(width) \
-{ \
- memory_read_byte_##width, \
- memory_read_word_##width, \
- memory_read_word_masked_##width, \
- memory_read_dword_##width, \
- memory_read_dword_masked_##width, \
- memory_read_qword_##width, \
- memory_read_qword_masked_##width, \
- memory_write_byte_##width, \
- memory_write_word_##width, \
- memory_write_word_masked_##width, \
- memory_write_dword_##width, \
- memory_write_dword_masked_##width, \
- memory_write_qword_##width, \
- memory_write_qword_masked_##width \
-}
-
-static const data_accessors memory_accessors[4][2] =
-{
- { ACCESSOR_GROUP(8le), ACCESSOR_GROUP(8be) },
- { ACCESSOR_GROUP(16le), ACCESSOR_GROUP(16be) },
- { ACCESSOR_GROUP(32le), ACCESSOR_GROUP(32be) },
- { ACCESSOR_GROUP(64le), ACCESSOR_GROUP(64be) }
+ // enable watchpoints by swapping in the watchpoint table
+ void enable_watchpoints(bool enable = true) { m_live_lookup = enable ? s_watchpoint_table : m_table; }
+
+ // table mapping helpers
+ UINT8 map_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, UINT8 staticentry = 0);
+ UINT8 derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &byteend) const;
+
+ // misc helpers
+ void mask_all_handlers(offs_t mask);
+ const char *handler_name(UINT8 entry) const;
+
+protected:
+ // determine table indexes based on the address
+ UINT32 level1_index_large(offs_t address) const { return address >> LEVEL2_BITS; }
+ UINT32 level2_index_large(UINT8 l1entry, offs_t address) const { return (1 << LEVEL1_BITS) + ((l1entry - SUBTABLE_BASE) << LEVEL2_BITS) + (address & ((1 << LEVEL2_BITS) - 1)); }
+ UINT32 level1_index(offs_t address) const { return m_large ? level1_index_large(address) : address; }
+ UINT32 level2_index(UINT8 l1entry, offs_t address) const { return m_large ? level2_index_large(l1entry, address) : 0; }
+
+ // table population/depopulation
+ void populate_range_mirrored(offs_t bytestart, offs_t byteend, offs_t bytemirror, UINT8 handler);
+ void populate_range(offs_t bytestart, offs_t byteend, UINT8 handler);
+ void depopulate_unused();
+
+ // subtable management
+ UINT8 subtable_alloc();
+ void subtable_realloc(UINT8 subentry);
+ int subtable_merge();
+ void subtable_release(UINT8 subentry);
+ UINT8 *subtable_open(offs_t l1index);
+ void subtable_close(offs_t l1index);
+ UINT8 *subtable_ptr(UINT8 entry) { return &m_table[level2_index(entry, 0)]; }
+
+ // internal state
+ UINT8 * m_table; // pointer to base of table
+ UINT8 * m_live_lookup; // current lookup
+ address_space & m_space; // pointer back to the space
+ bool m_large; // large memory model?
+
+ // subtable_data is an internal class with information about each subtable
+ class subtable_data
+ {
+ public:
+ subtable_data()
+ : m_checksum_valid(false),
+ m_checksum(0),
+ m_usecount(0) { }
+
+ bool m_checksum_valid; // is the checksum valid
+ UINT32 m_checksum; // checksum over all the bytes
+ UINT32 m_usecount; // number of times this has been used
+ };
+ subtable_data * m_subtable; // info about each subtable
+ UINT8 m_subtable_alloc; // number of subtables allocated
+
+ // static global read-only watchpoint table
+ static UINT8 s_watchpoint_table[1 << LEVEL1_BITS];
};
+// ======================> address_table_read
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
+// read access-specific version of an address table
+class address_table_read : public address_table
+{
+public:
+ // construction/destruction
+ address_table_read(address_space &space, bool large);
+ ~address_table_read();
-/* internal initialization */
-static void memory_init_spaces(running_machine *machine);
-static void memory_init_preflight(running_machine *machine);
-static void memory_init_populate(running_machine *machine);
-static void memory_init_map_entry(address_space *space, const address_map_entry *entry, read_or_write readorwrite);
-static void memory_init_allocate(running_machine *machine);
-static void memory_init_locate(running_machine *machine);
-static void memory_exit(running_machine &machine);
-
-/* memory mapping helpers */
-static void space_map_range(address_space *space, read_or_write readorwrite, int handlerbits, int handlerunitmask, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, genf *handler, void *object, const char *handler_name);
-static void *space_find_backing_memory(const address_space *space, offs_t addrstart, offs_t addrend);
-static int space_needs_backing_store(const address_space *space, const address_map_entry *entry);
-
-/* banking helpers */
-static genf *bank_find_or_allocate(const address_space *space, const char *tag, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read_or_write readorwrite);
-static STATE_POSTLOAD( bank_reattach );
+ // getters
+ virtual handler_entry &handler(UINT32 index) const;
+ handler_entry_read &handler_read(UINT32 index) const { assert(index < ARRAY_LENGTH(m_handlers)); return *m_handlers[index]; }
+
+private:
+ // internal unmapped handler
+ template<typename _UintType>
+ _UintType unmap_r(address_space &space, offs_t offset, _UintType mask)
+ {
+ if (m_space.log_unmap() && !m_space.debugger_access())
+ logerror("%s: unmapped %s memory read from %s\n", cpuexec_describe_context(&m_space.m_machine), m_space.name(), core_i64_hex_format(m_space.byte_to_address(offset), m_space.addrchars()));
+ return m_space.unmap();
+ }
+
+ // internal no-op handler
+ template<typename _UintType>
+ _UintType nop_r(address_space &space, offs_t offset, _UintType mask)
+ {
+ return m_space.unmap();
+ }
-/* table management */
-static UINT8 table_assign_handler(const address_space *space, handler_data **table, void *object, genf *handler, const char *handler_name, offs_t bytestart, offs_t byteend, offs_t bytemask);
-static void table_compute_subhandler(handler_data **table, UINT8 entry, read_or_write readorwrite, int spacebits, int spaceendian, int handlerbits, int handlerunitmask);
-static void table_populate_range(address_table *tabledata, offs_t bytestart, offs_t byteend, UINT8 handler);
-static void table_populate_range_mirrored(address_space *space, address_table *tabledata, offs_t bytestart, offs_t byteend, offs_t bytemirror, UINT8 handler);
-static UINT8 table_derive_range(const address_table *table, offs_t byteaddress, offs_t *bytestart, offs_t *byteend);
+ // internal watchpoint handler
+ template<typename _UintType>
+ _UintType watchpoint_r(address_space &space, offs_t offset, _UintType mask)
+ {
+ m_space.device().debug()->memory_read_hook(m_space, offset, mask);
+
+ UINT8 *oldtable = m_live_lookup;
+ m_live_lookup = m_table;
+ _UintType result;
+ if (sizeof(_UintType) == 1) result = m_space.read_byte(offset);
+ if (sizeof(_UintType) == 2) result = m_space.read_word(offset, mask);
+ if (sizeof(_UintType) == 4) result = m_space.read_dword(offset, mask);
+ if (sizeof(_UintType) == 8) result = m_space.read_qword(offset, mask);
+ m_live_lookup = oldtable;
+ return result;
+ }
-/* subtable management */
-static UINT8 subtable_alloc(address_table *tabledata);
-static void subtable_realloc(address_table *tabledata, UINT8 subentry);
-static int subtable_merge(address_table *tabledata);
-static void subtable_release(address_table *tabledata, UINT8 subentry);
-static UINT8 *subtable_open(address_table *tabledata, offs_t l1index);
-static void subtable_close(address_table *tabledata, offs_t l1index);
+ // internal state
+ handler_entry_read * m_handlers[256]; // array of user-installed handlers
+};
-/* direct memory ranges */
-static direct_range *direct_range_find(address_space *space, offs_t byteaddress, UINT8 *entry);
-static void direct_range_remove_intersecting(address_space *space, offs_t bytestart, offs_t byteend);
-/* memory block allocation */
-static void *block_allocate(const address_space *space, offs_t bytestart, offs_t byteend, void *memory);
-static address_map_entry *block_assign_intersecting(address_space *space, offs_t bytestart, offs_t byteend, UINT8 *base);
+// ======================> address_table_write
-/* internal handlers */
-static memory_handler get_stub_handler(read_or_write readorwrite, int spacedbits, int handlerdbits);
-static genf *get_static_handler(int handlerbits, int readorwrite, int which);
+// write access-specific version of an address table
+class address_table_write : public address_table
+{
+public:
+ // construction/destruction
+ address_table_write(address_space &space, bool large);
+ ~address_table_write();
-/* debugging */
-static const char *handler_to_string(const address_space *space, const address_table *table, UINT8 entry);
-static void dump_map(FILE *file, const address_space *space, const address_table *table);
-static void mem_dump(running_machine *machine);
+ // getters
+ virtual handler_entry &handler(UINT32 index) const;
+ handler_entry_write &handler_write(UINT32 index) const { assert(index < ARRAY_LENGTH(m_handlers)); return *m_handlers[index]; }
-/* input port handlers */
-static UINT8 input_port_read8(const input_port_config *port, offs_t offset);
-static UINT16 input_port_read16(const input_port_config *port, offs_t offset, UINT16 mem_mask);
-static UINT32 input_port_read32(const input_port_config *port, offs_t offset, UINT32 mem_mask);
-static UINT64 input_port_read64(const input_port_config *port, offs_t offset, UINT64 mem_mask);
+private:
+ // internal handlers
+ template<typename _UintType>
+ void unmap_w(address_space &space, offs_t offset, _UintType data, _UintType mask)
+ {
+ if (m_space.log_unmap() && !m_space.debugger_access())
+ logerror("%s: unmapped %s memory write to %s\n", cpuexec_describe_context(&m_space.m_machine), m_space.name(), core_i64_hex_format(m_space.byte_to_address(offset), m_space.addrchars()));
+ }
-/* output port handlers */
-static void input_port_write8(const input_port_config *port, offs_t offset, UINT8 data);
-static void input_port_write16(const input_port_config *port, offs_t offset, UINT16 data, UINT16 mem_mask);
-static void input_port_write32(const input_port_config *port, offs_t offset, UINT32 data, UINT32 mem_mask);
-static void input_port_write64(const input_port_config *port, offs_t offset, UINT64 data, UINT64 mem_mask);
+ template<typename _UintType>
+ void nop_w(address_space &space, offs_t offset, _UintType data, _UintType mask)
+ {
+ }
+ template<typename _UintType>
+ void watchpoint_w(address_space &space, offs_t offset, _UintType data, _UintType mask)
+ {
+ m_space.device().debug()->memory_write_hook(m_space, offset, data, 0xff);
+
+ UINT8 *oldtable = m_live_lookup;
+ m_live_lookup = m_table;
+ if (sizeof(_UintType) == 1) m_space.write_byte(offset, data);
+ if (sizeof(_UintType) == 2) m_space.write_word(offset, data, mask);
+ if (sizeof(_UintType) == 4) m_space.write_dword(offset, data, mask);
+ if (sizeof(_UintType) == 8) m_space.write_qword(offset, data, mask);
+ m_live_lookup = oldtable;
+ }
+ // internal state
+ handler_entry_write * m_handlers[256]; // array of user-installed handlers
+};
-/***************************************************************************
- INLINE FUNCTIONS
-***************************************************************************/
-/*-------------------------------------------------
- force_opbase_update - ensure that we update
- the opcode base
--------------------------------------------------*/
+// ======================> address_space_specific
-INLINE void force_opbase_update(const address_space *space)
+// this is a derived class of address_space with specific width, endianness, and table size
+template<typename _NativeType, endianness_t _Endian, bool _Large>
+class address_space_specific : public address_space
{
- address_space *spacerw = (address_space *)space;
- spacerw->direct.byteend = 0;
- spacerw->direct.bytestart = 1;
-}
+ typedef address_space_specific<_NativeType, _Endian, _Large> this_type;
+ // helpers to simplify core code
+ offs_t endian_xor(offs_t value) { if (_Endian == ENDIANNESS_BIG) value = ~value; return value; }
+ int endian_shift(int levalue, int bevalue) { return (_Endian == ENDIANNESS_LITTLE) ? levalue : bevalue; }
+ UINT32 read_lookup(offs_t byteaddress) const { return _Large ? m_read.lookup_live_large(byteaddress) : m_read.lookup_live_small(byteaddress); }
+ UINT32 write_lookup(offs_t byteaddress) const { return _Large ? m_write.lookup_live_large(byteaddress) : m_write.lookup_live_small(byteaddress); }
-/*-------------------------------------------------
- adjust_addresses - adjust addresses for a
- given address space in a standard fashion
--------------------------------------------------*/
+public:
+ // construction/destruction
+ address_space_specific(device_memory_interface &memory, int spacenum)
+ : address_space(memory, spacenum, _Large),
+ m_read(*this, _Large),
+ m_write(*this, _Large) { }
+
+ // accessors
+ virtual address_table_read &read() { return m_read; }
+ virtual address_table_write &write() { return m_write; }
-INLINE void adjust_addresses(const address_space *space, offs_t *start, offs_t *end, offs_t *mask, offs_t *mirror)
-{
- /* adjust start/end/mask values */
- if (*mask == 0)
- *mask = space->addrmask & ~*mirror;
- else
- *mask &= space->addrmask;
- *start &= ~*mirror & space->addrmask;
- *end &= ~*mirror & space->addrmask;
+ // watchpoint control
+ virtual void enable_read_watchpoints(bool enable = true) { m_read.enable_watchpoints(enable); }
+ virtual void enable_write_watchpoints(bool enable = true) { m_write.enable_watchpoints(enable); }
- /* adjust to byte values */
- *start = memory_address_to_byte(space, *start);
- *end = memory_address_to_byte_end(space, *end);
- *mask = memory_address_to_byte_end(space, *mask);
- *mirror = memory_address_to_byte(space, *mirror);
-}
+ // generate accessor table
+ virtual void accessors(data_accessors &accessors) const
+ {
+ accessors.read_byte = reinterpret_cast<UINT8 (*)(const address_space *, offs_t)>(&read_byte_static);
+ accessors.read_word = reinterpret_cast<UINT16 (*)(const address_space *, offs_t)>(&read_word_static);
+ accessors.read_word_masked = reinterpret_cast<UINT16 (*)(const address_space *, offs_t, UINT16)>(&read_word_masked_static);
+ accessors.read_dword = reinterpret_cast<UINT32 (*)(const address_space *, offs_t)>(&read_dword_static);
+ accessors.read_dword_masked = reinterpret_cast<UINT32 (*)(const address_space *, offs_t, UINT32)>(&read_dword_masked_static);
+ accessors.read_qword = reinterpret_cast<UINT64 (*)(const address_space *, offs_t)>(&read_qword_static);
+ accessors.read_qword_masked = reinterpret_cast<UINT64 (*)(const address_space *, offs_t, UINT64)>(&read_qword_masked_static);
+ accessors.write_byte = reinterpret_cast<void (*)(const address_space *, offs_t, UINT8)>(&write_byte_static);
+ accessors.write_word = reinterpret_cast<void (*)(const address_space *, offs_t, UINT16)>(&write_word_static);
+ accessors.write_word_masked = reinterpret_cast<void (*)(const address_space *, offs_t, UINT16, UINT16)>(&write_word_masked_static);
+ accessors.write_dword = reinterpret_cast<void (*)(const address_space *, offs_t, UINT32)>(&write_dword_static);
+ accessors.write_dword_masked = reinterpret_cast<void (*)(const address_space *, offs_t, UINT32, UINT32)>(&write_dword_masked_static);
+ accessors.write_qword = reinterpret_cast<void (*)(const address_space *, offs_t, UINT64)>(&write_qword_static);
+ accessors.write_qword_masked = reinterpret_cast<void (*)(const address_space *, offs_t, UINT64, UINT64)>(&write_qword_masked_static);
+ }
+ //
+ virtual void *get_read_ptr(offs_t byteaddress)
+ {
+ // perform the lookup
+ byteaddress &= m_bytemask;
+ UINT32 entry = read_lookup(byteaddress);
+ const handler_entry_read &handler = m_read.handler_read(entry);
+
+ // 8-bit case: RAM/ROM
+ if (entry >= STATIC_RAM)
+ return NULL;
+ return handler.ramptr(handler.byteoffset(byteaddress));
+ }
-/*-------------------------------------------------
- bank_references_space - return true if the
- given bank is referenced by a particular
- address space
--------------------------------------------------*/
+ virtual void *get_write_ptr(offs_t byteaddress)
+ {
+ // perform the lookup
+ byteaddress &= m_bytemask;
+ UINT32 entry = read_lookup(byteaddress);
+ const handler_entry_write &handler = m_write.handler_write(entry);
+
+ // 8-bit case: RAM/ROM
+ if (entry >= STATIC_RAM)
+ return NULL;
+ return handler.ramptr(handler.byteoffset(byteaddress));
+ }
-INLINE int bank_references_space(const bank_info *bank, const address_space *space)
-{
- bank_reference *ref;
+ // native read
+ _NativeType read_native(offs_t offset, _NativeType mask)
+ {
+ profiler_mark_start(PROFILER_MEMREAD);
+
+ // look up the handler
+ offs_t byteaddress = offset & m_bytemask;
+ UINT32 entry = read_lookup(byteaddress);
+ const handler_entry_read &handler = m_read.handler_read(entry);
+
+ // either read directly from RAM, or call the delegate
+ offset = handler.byteoffset(byteaddress) / sizeof(_NativeType);
+ _NativeType result;
+ if (entry < STATIC_RAM) result = *reinterpret_cast<_NativeType *>(handler.ramptr(offset * sizeof(_NativeType)));
+ else if (sizeof(_NativeType) == 1) result = handler.read8(*this, offset, mask);
+ else if (sizeof(_NativeType) == 2) result = handler.read16(*this, offset, mask);
+ else if (sizeof(_NativeType) == 4) result = handler.read32(*this, offset, mask);
+ else if (sizeof(_NativeType) == 8) result = handler.read64(*this, offset, mask);
+
+ profiler_mark_end();
+ return result;
+ }
- for (ref = bank->reflist; ref != NULL; ref = ref->next)
- if (ref->space == space)
- return TRUE;
- return FALSE;
-}
+ // native write
+ void write_native(offs_t offset, _NativeType data, _NativeType mask)
+ {
+ profiler_mark_start(PROFILER_MEMWRITE);
+ // look up the handler
+ offs_t byteaddress = offset & m_bytemask;
+ UINT32 entry = write_lookup(byteaddress);
+ const handler_entry_write &handler = m_write.handler_write(entry);
-/*-------------------------------------------------
- add_bank_reference - add a new address space
- reference to a bank
--------------------------------------------------*/
+ // either write directly to RAM, or call the delegate
+ offset = handler.byteoffset(byteaddress) / sizeof(_NativeType);
+ if (entry < STATIC_RAM)
+ {
+ _NativeType *dest = reinterpret_cast<_NativeType *>(handler.ramptr(offset * sizeof(_NativeType)));
+ *dest = (*dest & ~mask) | (data & mask);
+ }
+ else if (sizeof(_NativeType) == 1) handler.write8(*this, offset, data, mask);
+ else if (sizeof(_NativeType) == 2) handler.write16(*this, offset, data, mask);
+ else if (sizeof(_NativeType) == 4) handler.write32(*this, offset, data, mask);
+ else if (sizeof(_NativeType) == 8) handler.write64(*this, offset, data, mask);
-INLINE void add_bank_reference(bank_info *bank, const address_space *space)
-{
- bank_reference **refptr;
+ profiler_mark_end();
+ }
- /* make sure we don't already have a reference to the bank */
- for (refptr = &bank->reflist; *refptr != NULL; refptr = &(*refptr)->next)
- if ((*refptr)->space == space)
- return;
+ // read byte
+ UINT8 read_byte_direct(offs_t address)
+ {
+ if (sizeof(_NativeType) == 1)
+ return read_native(address, 0xff);
+
+ if (sizeof(_NativeType) > 1)
+ {
+ UINT32 shift = (endian_xor(address) & (sizeof(_NativeType) - 1)) * 8;
+ return read_native(address, (_NativeType)0xff << shift) >> shift;
+ }
+ }
+
+ // read word
+ UINT16 read_word_direct(offs_t address, UINT16 mask)
+ {
+ if (sizeof(_NativeType) == 2)
+ return read_native(address, mask);
- /* allocate a new entry and fill it */
- (*refptr) = auto_alloc(space->machine, bank_reference);
- (*refptr)->next = NULL;
- (*refptr)->space = space;
-}
+ if (sizeof(_NativeType) > 2)
+ {
+ UINT32 shift = (endian_xor(address) & (sizeof(_NativeType) - 2)) * 8;
+ return read_native(address, (_NativeType)mask << shift) >> shift;
+ }
+
+ if (sizeof(_NativeType) < 2)
+ {
+ UINT16 result = 0;
+ if (EXPECTED(mask & (0xff << endian_shift(0,8)))) result |= read_byte_direct(address + 0) << endian_shift(0,8);
+ if (EXPECTED(mask & (0xff << endian_shift(8,0)))) result |= read_byte_direct(address + 1) << endian_shift(8,0);
+ return result;
+ }
+ }
+ // read dword
+ UINT32 read_dword_direct(offs_t address, UINT32 mask)
+ {
+ if (sizeof(_NativeType) == 4)
+ return read_native(address, mask);
-/*-------------------------------------------------
- read_byte_generic - read a byte from an
- arbitrary address space
--------------------------------------------------*/
+ if (sizeof(_NativeType) > 4)
+ {
+ UINT32 shift = (endian_xor(address) & (sizeof(_NativeType) - 4)) * 8;
+ return read_native(address, (_NativeType)mask << shift) >> shift;
+ }
+
+ if (sizeof(_NativeType) < 4)
+ {
+ UINT32 result = 0;
+ if (EXPECTED(mask & (0xffff << endian_shift(0,16)))) result |= read_word_direct(address + 0, mask >> endian_shift(0,16)) << endian_shift(0,16);
+ if (EXPECTED(mask & (0xffff << endian_shift(16,0)))) result |= read_word_direct(address + 2, mask >> endian_shift(16,0)) << endian_shift(16,0);
+ return result;
+ }
+ }
-INLINE UINT8 read_byte_generic(const address_space *space, offs_t byteaddress)
-{
- const handler_data *handler;
- offs_t byteoffset;
- UINT32 entry;
- UINT8 result;
+ // read qword
+ UINT64 read_qword_direct(offs_t address, UINT64 mask)
+ {
+ if (sizeof(_NativeType) == 8)
+ return read_native(address, mask);
+
+ if (sizeof(_NativeType) < 8)
+ {
+ UINT64 result = 0;
+ if (EXPECTED(mask & (U64(0xffffffff) << endian_shift(0,32)))) result |= (UINT64)read_dword_direct(address + 0, mask >> endian_shift(0,32)) << endian_shift(0,32);
+ if (EXPECTED(mask & (U64(0xffffffff) << endian_shift(32,0)))) result |= (UINT64)read_dword_direct(address + 4, mask >> endian_shift(32,0)) << endian_shift(32,0);
+ return result;
+ }
+ }
+
+ // write byte
+ void write_byte_direct(offs_t address, UINT8 data)
+ {
+ if (sizeof(_NativeType) == 1)
+ return write_native(address, data, 0xff);
+
+ if (sizeof(_NativeType) > 1)
+ {
+ UINT32 shift = (endian_xor(address) & (sizeof(_NativeType) - 1)) * 8;
+ return write_native(address, (_NativeType)data << shift, (_NativeType)0xff << shift);
+ }
+ }
+
+ // write word
+ void write_word_direct(offs_t address, UINT16 data, UINT16 mask)
+ {
+ if (sizeof(_NativeType) == 2)
+ return write_native(address, data, mask);
+
+ if (sizeof(_NativeType) > 2)
+ {
+ UINT32 shift = (endian_xor(address) & (sizeof(_NativeType) - 2)) * 8;
+ return write_native(address, (_NativeType)data << shift, (_NativeType)mask << shift);
+ }
- profiler_mark_start(PROFILER_MEMREAD);
+ if (sizeof(_NativeType) < 2)
+ {
+ if (EXPECTED(mask & (0xff << endian_shift(0,8)))) write_byte_direct(address + 0, data >> endian_shift(0,8));
+ if (EXPECTED(mask & (0xff << endian_shift(8,0)))) write_byte_direct(address + 1, data >> endian_shift(8,0));
+ }
+ }
+
+ // write dword
+ void write_dword_direct(offs_t address, UINT32 data, UINT32 mask)
+ {
+ if (sizeof(_NativeType) == 4)
+ return write_native(address, data, mask);
+
+ if (sizeof(_NativeType) > 4)
+ {
+ UINT32 shift = (endian_xor(address) & (sizeof(_NativeType) - 4)) * 8;
+ return write_native(address, (_NativeType)data << shift, (_NativeType)mask << shift);
+ }
- byteaddress &= space->bytemask;
- entry = space->readlookup[LEVEL1_INDEX(byteaddress)];
- if (entry >= SUBTABLE_BASE)
- entry = space->readlookup[LEVEL2_INDEX(entry, byteaddress)];
- handler = space->read.handlers[entry];
+ if (sizeof(_NativeType) < 4)
+ {
+ if (EXPECTED(mask & (0xffff << endian_shift(0,16)))) write_word_direct(address + 0, data >> endian_shift(0,16), mask >> endian_shift(0,16));
+ if (EXPECTED(mask & (0xffff << endian_shift(16,0)))) write_word_direct(address + 2, data >> endian_shift(16,0), mask >> endian_shift(16,0));
+ }
+ }
+
+ // write qword
+ void write_qword_direct(offs_t address, UINT64 data, UINT64 mask)
+ {
+ if (sizeof(_NativeType) == 8)
+ return write_native(address, data, mask);
+
+ if (sizeof(_NativeType) < 8)
+ {
+ if (EXPECTED(mask & (U64(0xffffffff) << endian_shift(0,32)))) write_dword_direct(address + 0, data >> endian_shift(0,32), mask >> endian_shift(0,32));
+ if (EXPECTED(mask & (U64(0xffffffff) << endian_shift(32,0)))) write_dword_direct(address + 4, data >> endian_shift(32,0), mask >> endian_shift(32,0));
+ }
+ }
+
+ // virtual access to these functions
+ UINT8 read_byte(offs_t address) { return read_byte_direct(address); }
+ UINT16 read_word(offs_t address, UINT16 mask) { return read_word_direct(address, mask); }
+ UINT32 read_dword(offs_t address, UINT32 mask) { return read_dword_direct(address, mask); }
+ UINT64 read_qword(offs_t address, UINT64 mask) { return read_qword_direct(address, mask); }
+ void write_byte(offs_t address, UINT8 data) { write_byte_direct(address, data); }
+ void write_word(offs_t address, UINT16 data, UINT16 mask) { write_word_direct(address, data, mask); }
+ void write_dword(offs_t address, UINT32 data, UINT32 mask) { write_dword_direct(address, data, mask); }
+ void write_qword(offs_t address, UINT64 data, UINT64 mask) { write_qword_direct(address, data, mask); }
+
+ // static access to these functions
+ static UINT8 read_byte_static(this_type *space, offs_t address) { return space->read_byte_direct(address); }
+ static UINT16 read_word_static(this_type *space, offs_t address) { return space->read_word_direct(address, 0xffff); }
+ static UINT16 read_word_masked_static(this_type *space, offs_t address, UINT16 mask) { return space->read_word_direct(address, mask); }
+ static UINT32 read_dword_static(this_type *space, offs_t address) { return space->read_dword_direct(address, 0xffffffff); }
+ static UINT32 read_dword_masked_static(this_type *space, offs_t address, UINT32 mask) { return space->read_dword_direct(address, mask); }
+ static UINT64 read_qword_static(this_type *space, offs_t address) { return space->read_qword_direct(address, U64(0xffffffffffffffff)); }
+ static UINT64 read_qword_masked_static(this_type *space, offs_t address, UINT64 mask) { return space->read_qword_direct(address, mask); }
+ static void write_byte_static(this_type *space, offs_t address, UINT8 data) { space->write_byte_direct(address, data); }
+ static void write_word_static(this_type *space, offs_t address, UINT16 data) { space->write_word_direct(address, data, 0xffff); }
+ static void write_word_masked_static(this_type *space, offs_t address, UINT16 data, UINT16 mask) { space->write_word_direct(address, data, mask); }
+ static void write_dword_static(this_type *space, offs_t address, UINT32 data) { space->write_dword_direct(address, data, 0xffffffff); }
+ static void write_dword_masked_static(this_type *space, offs_t address, UINT32 data, UINT32 mask) { space->write_dword_direct(address, data, mask); }
+ static void write_qword_static(this_type *space, offs_t address, UINT64 data) { space->write_qword_direct(address, data, U64(0xffffffffffffffff)); }
+ static void write_qword_masked_static(this_type *space, offs_t address, UINT64 data, UINT64 mask) { space->write_qword_direct(address, data, mask); }
+
+ address_table_read m_read; // memory read lookup table
+ address_table_write m_write; // memory write lookup table
+};
- byteoffset = (byteaddress - handler->bytestart) & handler->bytemask;
- if (entry < STATIC_RAM)
- result = (*handler->bankbaseptr)[byteoffset];
- else
- result = (*handler->handler.read.shandler8)((const address_space *)handler->object, byteoffset);
+typedef address_space_specific<UINT8, ENDIANNESS_LITTLE, false> address_space_8le_small;
+typedef address_space_specific<UINT8, ENDIANNESS_BIG, false> address_space_8be_small;
+typedef address_space_specific<UINT16, ENDIANNESS_LITTLE, false> address_space_16le_small;
+typedef address_space_specific<UINT16, ENDIANNESS_BIG, false> address_space_16be_small;
+typedef address_space_specific<UINT32, ENDIANNESS_LITTLE, false> address_space_32le_small;
+typedef address_space_specific<UINT32, ENDIANNESS_BIG, false> address_space_32be_small;
+typedef address_space_specific<UINT64, ENDIANNESS_LITTLE, false> address_space_64le_small;
+typedef address_space_specific<UINT64, ENDIANNESS_BIG, false> address_space_64be_small;
- profiler_mark_end();
- return result;
-}
+typedef address_space_specific<UINT8, ENDIANNESS_LITTLE, true> address_space_8le_large;
+typedef address_space_specific<UINT8, ENDIANNESS_BIG, true> address_space_8be_large;
+typedef address_space_specific<UINT16, ENDIANNESS_LITTLE, true> address_space_16le_large;
+typedef address_space_specific<UINT16, ENDIANNESS_BIG, true> address_space_16be_large;
+typedef address_space_specific<UINT32, ENDIANNESS_LITTLE, true> address_space_32le_large;
+typedef address_space_specific<UINT32, ENDIANNESS_BIG, true> address_space_32be_large;
+typedef address_space_specific<UINT64, ENDIANNESS_LITTLE, true> address_space_64le_large;
+typedef address_space_specific<UINT64, ENDIANNESS_BIG, true> address_space_64be_large;
-/*-------------------------------------------------
- write_byte_generic - write a byte to an
- arbitrary address space
--------------------------------------------------*/
+// ======================> _memory_private
-INLINE void write_byte_generic(const address_space *space, offs_t byteaddress, UINT8 data)
+// holds internal state for the memory system
+struct _memory_private
{
- const handler_data *handler;
- offs_t byteoffset;
- UINT32 entry;
+ bool initialized; // have we completed initialization?
- profiler_mark_start(PROFILER_MEMWRITE);
+ UINT8 * bank_ptr[STATIC_COUNT]; // array of bank pointers
+ UINT8 * bankd_ptr[STATIC_COUNT]; // array of decrypted bank pointers
- byteaddress &= space->bytemask;
- entry = space->writelookup[LEVEL1_INDEX(byteaddress)];
- if (entry >= SUBTABLE_BASE)
- entry = space->writelookup[LEVEL2_INDEX(entry, byteaddress)];
- handler = space->write.handlers[entry];
+ simple_list<address_space> spacelist; // list of address spaces
+ simple_list<memory_block> blocklist; // head of the list of memory blocks
- byteoffset = (byteaddress - handler->bytestart) & handler->bytemask;
- if (entry < STATIC_RAM)
- (*handler->bankbaseptr)[byteoffset] = data;
- else
- (*handler->handler.write.shandler8)((const address_space *)handler->object, byteoffset, data);
+ simple_list<memory_bank> banklist; // data gathered for each bank
+ tagmap_t<memory_bank *> bankmap; // map for fast bank lookups
+ UINT8 banknext; // next bank to allocate
- profiler_mark_end();
-}
+ tagmap_t<void *> sharemap; // map for share lookups
+};
-/*-------------------------------------------------
- read_word_generic - read a word from an
- arbitrary address space
--------------------------------------------------*/
-INLINE UINT16 read_word_generic(const address_space *space, offs_t byteaddress, UINT16 mem_mask)
-{
- const handler_data *handler;
- offs_t byteoffset;
- UINT32 entry;
- UINT16 result;
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
- profiler_mark_start(PROFILER_MEMREAD);
+// global watchpoint table
+UINT8 address_table::s_watchpoint_table[1 << LEVEL1_BITS];
- byteaddress &= space->bytemask;
- entry = space->readlookup[LEVEL1_INDEX(byteaddress)];
- if (entry >= SUBTABLE_BASE)
- entry = space->readlookup[LEVEL2_INDEX(entry, byteaddress)];
- handler = space->read.handlers[entry];
- byteoffset = (byteaddress - handler->bytestart) & handler->bytemask;
- if (entry < STATIC_RAM)
- result = *(UINT16 *)&(*handler->bankbaseptr)[byteoffset & ~1];
- else
- result = (*handler->handler.read.shandler16)((const address_space *)handler->object, byteoffset >> 1, mem_mask);
- profiler_mark_end();
- return result;
-}
+//**************************************************************************
+// FUNCTION PROTOTYPES
+//**************************************************************************
+
+// banking helpers
+static STATE_POSTLOAD( bank_reattach );
+
+// debugging
+static void generate_memdump(running_machine *machine);
-/*-------------------------------------------------
- write_word_generic - write a word to an
- arbitrary address space
--------------------------------------------------*/
-INLINE void write_word_generic(const address_space *space, offs_t byteaddress, UINT16 data, UINT16 mem_mask)
+//**************************************************************************
+// CORE SYSTEM OPERATIONS
+//**************************************************************************
+
+//-------------------------------------------------
+// memory_init - initialize the memory system
+//-------------------------------------------------
+
+void memory_init(running_machine *machine)
{
- const handler_data *handler;
- offs_t byteoffset;
- UINT32 entry;
+ // allocate our private data
+ memory_private *memdata = machine->memory_data = auto_alloc_clear(machine, memory_private);
+ memdata->banknext = STATIC_BANK1;
+
+ // loop over devices and spaces within each device
+ device_memory_interface *memory = NULL;
+ for (bool gotone = machine->m_devicelist.first(memory); gotone; gotone = memory->next(memory))
+ for (int spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
+ {
+ // if there is a configuration for this space, we need an address space
+ const address_space_config *spaceconfig = memory->space_config(spacenum);
+ if (spaceconfig != NULL)
+ memdata->spacelist.append(address_space::allocate(*machine, *spaceconfig, *memory, spacenum));
+ }
- profiler_mark_start(PROFILER_MEMWRITE);
+ // construct and preprocess the address_map for each space
+ for (address_space *space = memdata->spacelist.first(); space != NULL; space = space->next())
+ space->prepare_map();
- byteaddress &= space->bytemask;
- entry = space->writelookup[LEVEL1_INDEX(byteaddress)];
- if (entry >= SUBTABLE_BASE)
- entry = space->writelookup[LEVEL2_INDEX(entry, byteaddress)];
- handler = space->write.handlers[entry];
+ // create the handlers from the resulting address maps
+ for (address_space *space = memdata->spacelist.first(); space != NULL; space = space->next())
+ space->populate_from_map();
- byteoffset = (byteaddress - handler->bytestart) & handler->bytemask;
- if (entry < STATIC_RAM)
- {
- UINT16 *dest = (UINT16 *)&(*handler->bankbaseptr)[byteoffset & ~1];
- *dest = (*dest & ~mem_mask) | (data & mem_mask);
- }
- else
- (*handler->handler.write.shandler16)((const address_space *)handler->object, byteoffset >> 1, data, mem_mask);
+ // allocate memory needed to back each address space
+ for (address_space *space = memdata->spacelist.first(); space != NULL; space = space->next())
+ space->allocate_memory();
- profiler_mark_end();
-}
+ // find all the allocated pointers
+ for (address_space *space = memdata->spacelist.first(); space != NULL; space = space->next())
+ space->locate_memory();
+
+ // register a callback to reset banks when reloading state
+ state_save_register_postload(machine, bank_reattach, NULL);
+ // dump the final memory configuration
+ generate_memdump(machine);
-/*-------------------------------------------------
- read_dword_generic - read a dword from an
- arbitrary address space
--------------------------------------------------*/
+ // borrow the first address space to be used as a dummy space
+ machine->m_nonspecific_space = memdata->spacelist.first();
-INLINE UINT32 read_dword_generic(const address_space *space, offs_t byteaddress, UINT32 mem_mask)
-{
- const handler_data *handler;
- offs_t byteoffset;
- UINT32 entry;
- UINT32 result;
+ // we are now initialized
+ memdata->initialized = true;
+}
- profiler_mark_start(PROFILER_MEMREAD);
- byteaddress &= space->bytemask;
- entry = space->readlookup[LEVEL1_INDEX(byteaddress)];
- if (entry >= SUBTABLE_BASE)
- entry = space->readlookup[LEVEL2_INDEX(entry, byteaddress)];
- handler = space->read.handlers[entry];
- byteoffset = (byteaddress - handler->bytestart) & handler->bytemask;
- if (entry < STATIC_RAM)
- result = *(UINT32 *)&(*handler->bankbaseptr)[byteoffset & ~3];
- else
- result = (*handler->handler.read.shandler32)((const address_space *)handler->object, byteoffset >> 2, mem_mask);
+//**************************************************************************
+// MEMORY BANKING
+//**************************************************************************
- profiler_mark_end();
- return result;
+//-------------------------------------------------
+// memory_configure_bank - configure the
+// addresses for a bank
+//-------------------------------------------------
+
+void memory_configure_bank(running_machine *machine, const char *tag, int startentry, int numentries, void *base, offs_t stride)
+{
+ // validation checks
+ memory_bank *bank = machine->memory_data->bankmap.find_hash_only(tag);
+ if (bank == NULL)
+ fatalerror("memory_configure_bank called for unknown bank '%s'", tag);
+ if (base == NULL)
+ fatalerror("memory_configure_bank called NULL base");
+
+ // fill in the requested bank entries (backwards to improve allocation)
+ for (int entrynum = startentry + numentries - 1; entrynum >= startentry; entrynum--)
+ bank->configure(entrynum, reinterpret_cast<UINT8 *>(base) + (entrynum - startentry) * stride);
}
-/*-------------------------------------------------
- write_dword_generic - write a dword to an
- arbitrary address space
--------------------------------------------------*/
+//-------------------------------------------------
+// memory_configure_bank_decrypted - configure
+// the decrypted addresses for a bank
+//-------------------------------------------------
-INLINE void write_dword_generic(const address_space *space, offs_t byteaddress, UINT32 data, UINT32 mem_mask)
+void memory_configure_bank_decrypted(running_machine *machine, const char *tag, int startentry, int numentries, void *base, offs_t stride)
{
- const handler_data *handler;
- offs_t byteoffset;
- UINT32 entry;
+ // validation checks
+ memory_bank *bank = machine->memory_data->bankmap.find_hash_only(tag);
+ if (bank == NULL)
+ fatalerror("memory_configure_bank_decrypted called for unknown bank '%s'", tag);
+ if (base == NULL)
+ fatalerror("memory_configure_bank_decrypted called NULL base");
- profiler_mark_start(PROFILER_MEMWRITE);
+ // fill in the requested bank entries (backwards to improve allocation)
+ for (int entrynum = startentry + numentries - 1; entrynum >= startentry; entrynum--)
+ bank->configure_decrypted(entrynum, reinterpret_cast<UINT8 *>(base) + (entrynum - startentry) * stride);
+}
- byteaddress &= space->bytemask;
- entry = space->writelookup[LEVEL1_INDEX(byteaddress)];
- if (entry >= SUBTABLE_BASE)
- entry = space->writelookup[LEVEL2_INDEX(entry, byteaddress)];
- handler = space->write.handlers[entry];
- byteoffset = (byteaddress - handler->bytestart) & handler->bytemask;
- if (entry < STATIC_RAM)
- {
- UINT32 *dest = (UINT32 *)&(*handler->bankbaseptr)[byteoffset & ~3];
- *dest = (*dest & ~mem_mask) | (data & mem_mask);
- }
- else
- (*handler->handler.write.shandler32)((const address_space *)handler->object, byteoffset >> 2, data, mem_mask);
+//-------------------------------------------------
+// memory_set_bank - select one pre-configured
+// entry to be the new bank base
+//-------------------------------------------------
+
+void memory_set_bank(running_machine *machine, const char *tag, int entrynum)
+{
+ // validation checks
+ memory_bank *bank = machine->memory_data->bankmap.find_hash_only(tag);
+ if (bank == NULL)
+ fatalerror("memory_set_bank called for unknown bank '%s'", tag);
- profiler_mark_end();
+ // set the base
+ bank->set_entry(entrynum);
}
-/*-------------------------------------------------
- read_qword_generic - read a qword from an
- arbitrary address space
--------------------------------------------------*/
+//-------------------------------------------------
+// memory_get_bank - return the currently
+// selected bank
+//-------------------------------------------------
-INLINE UINT64 read_qword_generic(const address_space *space, offs_t byteaddress, UINT64 mem_mask)
+int memory_get_bank(running_machine *machine, const char *tag)
{
- const handler_data *handler;
- offs_t byteoffset;
- UINT32 entry;
- UINT64 result;
+ // validation checks
+ memory_bank *bank = machine->memory_data->bankmap.find_hash_only(tag);
+ if (bank == NULL)
+ fatalerror("memory_get_bank called for unknown bank '%s'", tag);
- profiler_mark_start(PROFILER_MEMREAD);
+ // return the current entry
+ return bank->entry();
+}
- byteaddress &= space->bytemask;
- entry = space->readlookup[LEVEL1_INDEX(byteaddress)];
- if (entry >= SUBTABLE_BASE)
- entry = space->readlookup[LEVEL2_INDEX(entry, byteaddress)];
- handler = space->read.handlers[entry];
- byteoffset = (byteaddress - handler->bytestart) & handler->bytemask;
- if (entry < STATIC_RAM)
- result = *(UINT64 *)&(*handler->bankbaseptr)[byteoffset & ~7];
- else
- result = (*handler->handler.read.shandler64)((const address_space *)handler->object, byteoffset >> 3, mem_mask);
+//-------------------------------------------------
+// memory_set_bankptr - set the base of a bank
+//-------------------------------------------------
- profiler_mark_end();
- return result;
+void memory_set_bankptr(running_machine *machine, const char *tag, void *base)
+{
+ // validation checks
+ memory_bank *bank = machine->memory_data->bankmap.find_hash_only(tag);
+ if (bank == NULL)
+ throw emu_fatalerror("memory_set_bankptr called for unknown bank '%s'", tag);
+
+ // set the base
+ bank->set_base(base);
}
-/*-------------------------------------------------
- write_qword_generic - write a qword to an
- arbitrary address space
--------------------------------------------------*/
+//-------------------------------------------------
+// memory_dump - dump the internal memory tables
+// to the given file
+//-------------------------------------------------
-INLINE void write_qword_generic(const address_space *space, offs_t byteaddress, UINT64 data, UINT64 mem_mask)
+void memory_dump(running_machine *machine, FILE *file)
{
- const handler_data *handler;
- offs_t offset;
- UINT32 entry;
+ // skip if we can't open the file
+ if (file == NULL)
+ return;
+
+ // loop over address spaces
+ for (address_space *space = machine->memory_data->spacelist.first(); space != NULL; space = space->next())
+ {
+ fprintf(file, "\n\n"
+ "====================================================\n"
+ "Device '%s' %s address space read handler dump\n"
+ "====================================================\n", space->device().tag(), space->name());
+ space->dump_map(file, ROW_READ);
+
+ fprintf(file, "\n\n"
+ "====================================================\n"
+ "Device '%s' %s address space write handler dump\n"
+ "====================================================\n", space->device().tag(), space->name());
+ space->dump_map(file, ROW_WRITE);
+ }
+}
- profiler_mark_start(PROFILER_MEMWRITE);
- byteaddress &= space->bytemask;
- entry = space->writelookup[LEVEL1_INDEX(byteaddress)];
- if (entry >= SUBTABLE_BASE)
- entry = space->writelookup[LEVEL2_INDEX(entry, byteaddress)];
- handler = space->write.handlers[entry];
+//-------------------------------------------------
+// generate_memdump - internal memory dump
+//-------------------------------------------------
- offset = (byteaddress - handler->bytestart) & handler->bytemask;
- if (entry < STATIC_RAM)
+static void generate_memdump(running_machine *machine)
+{
+ if (MEM_DUMP)
{
- UINT64 *dest = (UINT64 *)&(*handler->bankbaseptr)[offset & ~7];
- *dest = (*dest & ~mem_mask) | (data & mem_mask);
+ FILE *file = fopen("memdump.log", "w");
+ if (file)
+ {
+ memory_dump(machine, file);
+ fclose(file);
+ }
}
- else
- (*handler->handler.write.shandler64)((const address_space *)handler->object, offset >> 3, data, mem_mask);
+}
+
- profiler_mark_end();
+//-------------------------------------------------
+// bank_reattach - reconnect banks after a load
+//-------------------------------------------------
+
+static STATE_POSTLOAD( bank_reattach )
+{
+ // for each non-anonymous bank, explicitly reset its entry
+ for (memory_bank *bank = machine->memory_data->banklist.first(); bank != NULL; bank = bank->next())
+ if (!bank->anonymous() && bank->entry() != BANK_ENTRY_UNSPECIFIED)
+ bank->set_entry(bank->entry());
}
-/***************************************************************************
- CORE SYSTEM OPERATIONS
-***************************************************************************/
+//**************************************************************************
+// ADDRESS SPACE
+//**************************************************************************
-/*-------------------------------------------------
- memory_init - initialize the memory system
--------------------------------------------------*/
+//-------------------------------------------------
+// address_space - constructor
+//-------------------------------------------------
-void memory_init(running_machine *machine)
+address_space::address_space(device_memory_interface &memory, int spacenum, bool large)
+ : machine(memory.device().machine),
+ cpu(&memory.device()),
+ m_machine(*memory.device().machine),
+ m_next(NULL),
+ m_config(*memory.space_config(spacenum)),
+ m_device(memory.device()),
+ m_map(NULL),
+ m_addrmask(0xffffffffUL >> (32 - m_config.m_addrbus_width)),
+ m_bytemask(address_to_byte_end(m_addrmask)),
+ m_logaddrmask(0xffffffffUL >> (32 - m_config.m_logaddr_width)),
+ m_logbytemask(address_to_byte_end(m_logaddrmask)),
+ m_unmap(0),
+ m_spacenum(spacenum),
+ m_debugger_access(false),
+ m_log_unmap(true),
+ m_direct(*auto_alloc(memory.device().machine, direct_read_data(*this))),
+ m_name(memory.space_config(spacenum)->name()),
+ m_addrchars((m_config.m_databus_width + 3) / 4),
+ m_logaddrchars((m_config.m_logaddr_width + 3) / 4)
{
- memory_private *memdata;
+ // notify the device
+ memory.set_address_space(spacenum, *this);
+}
+
- machine->add_notifier(MACHINE_NOTIFY_EXIT, memory_exit);
+//-------------------------------------------------
+// ~address_space - destructor
+//-------------------------------------------------
- /* allocate our private data */
- memdata = machine->memory_data = auto_alloc_clear(machine, memory_private);
+address_space::~address_space()
+{
+ global_free(&m_direct);
+ global_free(m_map);
+}
- /* build up the list of address spaces */
- memory_init_spaces(machine);
- /* preflight the memory handlers and check banks */
- memory_init_preflight(machine);
+//-------------------------------------------------
+// allocate - static smart allocator of subtypes
+//-------------------------------------------------
- /* then fill in the tables */
- memory_init_populate(machine);
+address_space &address_space::allocate(running_machine &machine, const address_space_config &config, device_memory_interface &memory, int spacenum)
+{
+ // allocate one of the appropriate type
+ bool large = (config.addr2byte_end(0xffffffffUL >> (32 - config.m_addrbus_width)) >= (1 << 18));
- /* allocate any necessary memory */
- memory_init_allocate(machine);
+ switch (config.data_width())
+ {
+ case 8:
+ if (config.endianness() == ENDIANNESS_LITTLE)
+ {
+ if (large)
+ return *auto_alloc(&machine, address_space_8le_large(memory, spacenum));
+ else
+ return *auto_alloc(&machine, address_space_8le_small(memory, spacenum));
+ }
+ else
+ {
+ if (large)
+ return *auto_alloc(&machine, address_space_8be_large(memory, spacenum));
+ else
+ return *auto_alloc(&machine, address_space_8be_small(memory, spacenum));
+ }
- /* find all the allocated pointers */
- memory_init_locate(machine);
+ case 16:
+ if (config.endianness() == ENDIANNESS_LITTLE)
+ {
+ if (large)
+ return *auto_alloc(&machine, address_space_16le_large(memory, spacenum));
+ else
+ return *auto_alloc(&machine, address_space_16le_small(memory, spacenum));
+ }
+ else
+ {
+ if (large)
+ return *auto_alloc(&machine, address_space_16be_large(memory, spacenum));
+ else
+ return *auto_alloc(&machine, address_space_16be_small(memory, spacenum));
+ }
- /* dump the final memory configuration */
- mem_dump(machine);
+ case 32:
+ if (config.endianness() == ENDIANNESS_LITTLE)
+ {
+ if (large)
+ return *auto_alloc(&machine, address_space_32le_large(memory, spacenum));
+ else
+ return *auto_alloc(&machine, address_space_32le_small(memory, spacenum));
+ }
+ else
+ {
+ if (large)
+ return *auto_alloc(&machine, address_space_32be_large(memory, spacenum));
+ else
+ return *auto_alloc(&machine, address_space_32be_small(memory, spacenum));
+ }
- /* we are now initialized */
- memdata->initialized = TRUE;
+ case 64:
+ if (config.endianness() == ENDIANNESS_LITTLE)
+ {
+ if (large)
+ return *auto_alloc(&machine, address_space_64le_large(memory, spacenum));
+ else
+ return *auto_alloc(&machine, address_space_64le_small(memory, spacenum));
+ }
+ else
+ {
+ if (large)
+ return *auto_alloc(&machine, address_space_64be_large(memory, spacenum));
+ else
+ return *auto_alloc(&machine, address_space_64be_small(memory, spacenum));
+ }
+ }
+ throw emu_fatalerror("Invalid width %d specified for address_space::allocate", config.data_width());
}
+//-------------------------------------------------
+// adjust_addresses - adjust addresses for a
+// given address space in a standard fashion
+//-------------------------------------------------
-/***************************************************************************
- DIRECT ACCESS CONTROL
-***************************************************************************/
+inline void address_space::adjust_addresses(offs_t &start, offs_t &end, offs_t &mask, offs_t &mirror)
+{
+ // adjust start/end/mask values
+ if (mask == 0)
+ mask = m_addrmask & ~mirror;
+ else
+ mask &= m_addrmask;
+ start &= ~mirror & m_addrmask;
+ end &= ~mirror & m_addrmask;
+
+ // adjust to byte values
+ start = address_to_byte(start);
+ end = address_to_byte_end(end);
+ mask = address_to_byte_end(mask);
+ mirror = address_to_byte(mirror);
+}
-/*-------------------------------------------------
- memory_set_decrypted_region - registers an
- address range as having a decrypted data
- pointer
--------------------------------------------------*/
-void memory_set_decrypted_region(const address_space *space, offs_t addrstart, offs_t addrend, void *base)
+//-------------------------------------------------
+// prepare_map - allocate the address map and
+// walk through it to find implcit memory regions
+// and identify shared regions
+//-------------------------------------------------
+
+void address_space::prepare_map()
{
- offs_t bytestart = memory_address_to_byte(space, addrstart);
- offs_t byteend = memory_address_to_byte_end(space, addrend);
- int found = FALSE;
- bank_info *bank;
+ const region_info *devregion = (m_spacenum == ADDRESS_SPACE_0) ? m_machine.region(m_device.tag()) : NULL;
+ UINT32 devregionsize = (devregion != NULL) ? devregion->bytes() : 0;
+
+ // allocate the address map
+ m_map = global_alloc(address_map(m_device.baseconfig(), m_spacenum));
- /* loop over banks looking for a match */
- for (bank = space->machine->memory_data->banklist; bank != NULL; bank = bank->next)
+ // extract global parameters specified by the map
+ m_unmap = (m_map->m_unmapval == 0) ? 0 : ~0;
+ if (m_map->m_globalmask != 0)
{
- /* consider this bank if it is used for reading and matches the address space */
- if (bank->read && bank_references_space(bank, space))
+ m_addrmask = m_map->m_globalmask;
+ m_bytemask = address_to_byte_end(m_addrmask);
+ }
+
+ // make a pass over the address map, adjusting for the device and getting memory pointers
+ for (address_map_entry *entry = m_map->m_entrylist.first(); entry != NULL; entry = entry->next())
+ {
+ // if we have a share entry, add it to our map
+ if (entry->m_share != NULL)
+ m_machine.memory_data->sharemap.add(entry->m_share, UNMAPPED_SHARE_PTR, false);
+
+ // computed adjusted addresses first
+ entry->m_bytestart = entry->m_addrstart;
+ entry->m_byteend = entry->m_addrend;
+ entry->m_bytemirror = entry->m_addrmirror;
+ entry->m_bytemask = entry->m_addrmask;
+ adjust_addresses(entry->m_bytestart, entry->m_byteend, entry->m_bytemask, entry->m_bytemirror);
+
+ // if this is a ROM handler without a specified region, attach it to the implicit region
+ if (m_spacenum == ADDRESS_SPACE_0 && entry->m_read.m_type == AMH_ROM && entry->m_region == NULL)
{
- /* verify that the region fully covers the decrypted range */
- if (bank->bytestart >= bytestart && bank->byteend <= byteend)
+ // make sure it fits within the memory region before doing so, however
+ if (entry->m_byteend < devregionsize)
{
- /* set the decrypted pointer for the corresponding memory bank */
- space->machine->memory_data->bankd_ptr[bank->index] = (UINT8 *)base + bank->bytestart - bytestart;
- found = TRUE;
-
- /* if we are executing from here, force an opcode base update */
- if (space->direct.entry == bank->index)
- force_opbase_update(space);
+ entry->m_region = m_device.tag();
+ entry->m_rgnoffs = entry->m_bytestart;
}
+ }
- /* fatal error if the decrypted region straddles the bank */
- else if (bank->bytestart < byteend && bank->byteend > bytestart)
- fatalerror("memory_set_decrypted_region found straddled region %08X-%08X for device '%s'", bytestart, byteend, space->cpu->tag());
+ // validate adjusted addresses against implicit regions
+ if (entry->m_region != NULL && entry->m_share == NULL && entry->m_baseptr == NULL)
+ {
+ const region_info *region = m_machine.region(entry->m_region);
+ if (region == NULL)
+ fatalerror("Error: device '%s' %s space memory map entry %X-%X references non-existant region \"%s\"", m_device.tag(), m_name, entry->m_addrstart, entry->m_addrend, entry->m_region);
+
+ // validate the region
+ if (entry->m_rgnoffs + (entry->m_byteend - entry->m_bytestart + 1) > region->bytes())
+ fatalerror("Error: device '%s' %s space memory map entry %X-%X extends beyond region \"%s\" size (%X)", m_device.tag(), m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, region->bytes());
}
+
+ // convert any region-relative entries to their memory pointers
+ if (entry->m_region != NULL)
+ entry->m_memory = m_machine.region(entry->m_region)->base() + entry->m_rgnoffs;
}
- /* fatal error as well if we didn't find any relevant memory banks */
- if (!found)
- fatalerror("memory_set_decrypted_region unable to find matching region %08X-%08X for device '%s'", bytestart, byteend, space->cpu->tag());
+ // now loop over all the handlers and enforce the address mask
+ read().mask_all_handlers(m_bytemask);
+ write().mask_all_handlers(m_bytemask);
}
-/*-------------------------------------------------
- memory_set_direct_update_handler - register a
- handler for opcode base changes on a given
- device
--------------------------------------------------*/
+//-------------------------------------------------
+// populate_from_map - walk the map in reverse
+// order and install the appropriate handler for
+// each case
+//-------------------------------------------------
-direct_update_func memory_set_direct_update_handler(const address_space *space, direct_update_func function)
+void address_space::populate_from_map()
{
- address_space *spacerw = (address_space *)space;
- direct_update_func old = spacerw->directupdate;
- spacerw->directupdate = function;
- return old;
+ // no map, nothing to do
+ if (m_map == NULL)
+ return;
+
+ // install the handlers, using the original, unadjusted memory map
+ const address_map_entry *last_entry = NULL;
+ while (last_entry != m_map->m_entrylist.first())
+ {
+ // find the entry before the last one we processed
+ const address_map_entry *entry;
+ for (entry = m_map->m_entrylist.first(); entry->next() != last_entry; entry = entry->next()) ;
+ last_entry = entry;
+
+ // map both read and write halves
+ populate_map_entry(*entry, ROW_READ);
+ populate_map_entry(*entry, ROW_WRITE);
+ }
}
-/*-------------------------------------------------
- memory_set_direct_region - called by device
- cores to update the opcode base for the given
- address
--------------------------------------------------*/
+//-------------------------------------------------
+// populate_map_entry - map a single read or
+// write entry based on information from an
+// address map entry
+//-------------------------------------------------
-int memory_set_direct_region(const address_space *space, offs_t *byteaddress)
+void address_space::populate_map_entry(const address_map_entry &entry, read_or_write readorwrite)
{
- memory_private *memdata = space->machine->memory_data;
- address_space *spacerw = (address_space *)space;
- UINT8 *base = NULL, *based = NULL;
- const handler_data *handlers;
- direct_range *range;
- offs_t maskedbits;
- offs_t overrideaddress = *byteaddress;
- UINT8 entry;
+ const map_handler_data &data = (readorwrite == ROW_READ) ? entry.m_read : entry.m_write;
+ bindable_object *object;
+ device_t *device;
- /* allow overrides */
- if (spacerw->directupdate != NULL)
+ // based on the handler type, alter the bits, name, funcptr, and object
+ switch (data.m_type)
{
- overrideaddress = (*spacerw->directupdate)(spacerw, overrideaddress, &spacerw->direct);
- if (overrideaddress == ~0)
- return TRUE;
+ case AMH_NONE:
+ return;
- *byteaddress = overrideaddress;
- }
+ case AMH_ROM:
+ // writes to ROM are no-ops
+ if (readorwrite == ROW_WRITE)
+ return;
+ // fall through to the RAM case otherwise
- /* remove the masked bits (we'll put them back later) */
- maskedbits = overrideaddress & ~spacerw->bytemask;
+ case AMH_RAM:
+ install_ram(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, readorwrite);
+ break;
- /* find or allocate a matching range */
- range = direct_range_find(spacerw, overrideaddress, &entry);
+ case AMH_NOP:
+ unmap(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, readorwrite, true);
+ break;
- /* keep track of current entry */
- spacerw->direct.entry = entry;
+ case AMH_UNMAP:
+ unmap(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, readorwrite, false);
+ break;
- /* if we don't map to a bank, return FALSE */
- if (entry < STATIC_BANK1 || entry >= STATIC_RAM)
- {
- /* ensure future updates to land here as well until we get back into a bank */
- spacerw->direct.byteend = 0;
- spacerw->direct.bytestart = 1;
- return FALSE;
- }
+ case AMH_DRIVER_DELEGATE:
+ case AMH_DEVICE_DELEGATE:
+ if (data.m_type == AMH_DRIVER_DELEGATE)
+ {
+ object = m_machine.driver_data<driver_data_t>();
+ if (object == NULL)
+ throw emu_fatalerror("Attempted to map a driver delegate in space %s of device '%s' when there is no driver data\n", m_name, m_device.tag());
+ }
+ else
+ {
+ object = m_machine.device(data.m_tag);
+ if (object == NULL)
+ throw emu_fatalerror("Attempted to map a non-existent device '%s' in space %s of device '%s'\n", data.m_tag, m_name, m_device.tag());
+ }
- /* if no decrypted opcodes, point to the same base */
- base = memdata->bank_ptr[entry];
- based = memdata->bankd_ptr[entry];
- if (based == NULL)
- based = base;
+ if (readorwrite == ROW_READ)
+ switch (data.m_bits)
+ {
+ case 8: install_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read8_delegate(entry.m_rproto8, *object), data.m_mask); break;
+ case 16: install_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read16_delegate(entry.m_rproto16, *object), data.m_mask); break;
+ case 32: install_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read32_delegate(entry.m_rproto32, *object), data.m_mask); break;
+ case 64: install_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read64_delegate(entry.m_rproto64, *object), data.m_mask); break;
+ }
+ else
+ switch (data.m_bits)
+ {
+ case 8: install_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write8_delegate(entry.m_wproto8, *object), data.m_mask); break;
+ case 16: install_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write16_delegate(entry.m_wproto16, *object), data.m_mask); break;
+ case 32: install_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write32_delegate(entry.m_wproto32, *object), data.m_mask); break;
+ case 64: install_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write64_delegate(entry.m_wproto64, *object), data.m_mask); break;
+ }
+ break;
+
+ case AMH_LEGACY_SPACE_HANDLER:
+ if (readorwrite == ROW_READ)
+ switch (data.m_bits)
+ {
+ case 8: install_legacy_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rspace8, data.m_name, data.m_mask); break;
+ case 16: install_legacy_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rspace16, data.m_name, data.m_mask); break;
+ case 32: install_legacy_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rspace32, data.m_name, data.m_mask); break;
+ case 64: install_legacy_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rspace64, data.m_name, data.m_mask); break;
+ }
+ else
+ switch (data.m_bits)
+ {
+ case 8: install_legacy_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wspace8, data.m_name, data.m_mask); break;
+ case 16: install_legacy_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wspace16, data.m_name, data.m_mask); break;
+ case 32: install_legacy_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wspace32, data.m_name, data.m_mask); break;
+ case 64: install_legacy_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wspace64, data.m_name, data.m_mask); break;
+ }
+ break;
+
+ case AMH_LEGACY_DEVICE_HANDLER:
+ device = m_machine.device(data.m_tag);
+ if (device == NULL)
+ fatalerror("Attempted to map a non-existent device '%s' in space %s of device '%s'\n", data.m_tag, m_name, m_device.tag());
+
+ if (readorwrite == ROW_READ)
+ switch (data.m_bits)
+ {
+ case 8: install_legacy_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice8, data.m_name, data.m_mask); break;
+ case 16: install_legacy_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice16, data.m_name, data.m_mask); break;
+ case 32: install_legacy_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice32, data.m_name, data.m_mask); break;
+ case 64: install_legacy_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice64, data.m_name, data.m_mask); break;
+ }
+ else
+ switch (data.m_bits)
+ {
+ case 8: install_legacy_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice8, data.m_name, data.m_mask); break;
+ case 16: install_legacy_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice16, data.m_name, data.m_mask); break;
+ case 32: install_legacy_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice32, data.m_name, data.m_mask); break;
+ case 64: install_legacy_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice64, data.m_name, data.m_mask); break;
+ }
+ break;
- /* compute the adjusted base */
- handlers = spacerw->read.handlers[entry];
- spacerw->direct.bytemask = handlers->bytemask;
- spacerw->direct.raw = base - (handlers->bytestart & spacerw->direct.bytemask);
- spacerw->direct.decrypted = based - (handlers->bytestart & spacerw->direct.bytemask);
- spacerw->direct.bytestart = maskedbits | range->bytestart;
- spacerw->direct.byteend = maskedbits | range->byteend;
- return TRUE;
+ case AMH_PORT:
+ install_port(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror,
+ (readorwrite == ROW_READ) ? data.m_tag : NULL,
+ (readorwrite == ROW_WRITE) ? data.m_tag : NULL);
+ break;
+
+ case AMH_BANK:
+ install_bank(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror,
+ (readorwrite == ROW_READ) ? data.m_tag : NULL,
+ (readorwrite == ROW_WRITE) ? data.m_tag : NULL);
+ break;
+ }
}
-/*-------------------------------------------------
- memory_get_read_ptr - return a pointer the
- memory byte provided in the given address
- space, or NULL if it is not mapped to a bank
--------------------------------------------------*/
+//-------------------------------------------------
+// allocate_memory - determine all neighboring
+// address ranges and allocate memory to back
+// them
+//-------------------------------------------------
-void *memory_get_read_ptr(const address_space *space, offs_t byteaddress)
+void address_space::allocate_memory()
{
- const handler_data *handler;
- offs_t byteoffset;
- UINT8 entry;
+ simple_list<memory_block> &blocklist = m_machine.memory_data->blocklist;
- /* perform the lookup */
- byteaddress &= space->bytemask;
- entry = space->read.table[LEVEL1_INDEX(byteaddress)];
- if (entry >= SUBTABLE_BASE)
- entry = space->read.table[LEVEL2_INDEX(entry, byteaddress)];
- handler = space->read.handlers[entry];
+ // make a first pass over the memory map and track blocks with hardcoded pointers
+ // we do this to make sure they are found by space_find_backing_memory first
+ memory_block *prev_memblock_tail = blocklist.last();
+ for (address_map_entry *entry = m_map->m_entrylist.first(); entry != NULL; entry = entry->next())
+ if (entry->m_memory != NULL)
+ blocklist.append(*auto_alloc(&m_machine, memory_block(*this, entry->m_bytestart, entry->m_byteend, entry->m_memory)));
- /* 8-bit case: RAM/ROM */
- if (entry >= STATIC_RAM)
- return NULL;
- byteoffset = (byteaddress - handler->bytestart) & handler->bytemask;
- return &(*handler->bankbaseptr)[byteoffset];
-}
+ // loop over all blocks just allocated and assign pointers from them
+ address_map_entry *unassigned = NULL;
+ memory_block *first_new_block = (prev_memblock_tail != NULL) ? prev_memblock_tail->next() : blocklist.first();
+ for (memory_block *memblock = first_new_block; memblock != NULL; memblock = memblock->next())
+ unassigned = block_assign_intersecting(memblock->bytestart(), memblock->byteend(), memblock->data());
+ // if we don't have an unassigned pointer yet, try to find one
+ if (unassigned == NULL)
+ unassigned = block_assign_intersecting(~0, 0, NULL);
-/*-------------------------------------------------
- memory_get_write_ptr - return a pointer the
- memory byte provided in the given address
- space, or NULL if it is not mapped to a
- writeable bank
--------------------------------------------------*/
+ // loop until we've assigned all memory in this space
+ while (unassigned != NULL)
+ {
+ // work in MEMORY_BLOCK_CHUNK-sized chunks
+ offs_t curblockstart = unassigned->m_bytestart / MEMORY_BLOCK_CHUNK;
+ offs_t curblockend = unassigned->m_byteend / MEMORY_BLOCK_CHUNK;
-void *memory_get_write_ptr(const address_space *space, offs_t byteaddress)
-{
- const handler_data *handler;
- offs_t byteoffset;
- UINT8 entry;
+ // loop while we keep finding unassigned blocks in neighboring MEMORY_BLOCK_CHUNK chunks
+ bool changed;
+ do
+ {
+ changed = false;
- /* perform the lookup */
- byteaddress &= space->bytemask;
- entry = space->write.table[LEVEL1_INDEX(byteaddress)];
- if (entry >= SUBTABLE_BASE)
- entry = space->write.table[LEVEL2_INDEX(entry, byteaddress)];
- handler = space->write.handlers[entry];
+ // scan for unmapped blocks in the adjusted map
+ for (address_map_entry *entry = m_map->m_entrylist.first(); entry != NULL; entry = entry->next())
+ if (entry->m_memory == NULL && entry != unassigned && needs_backing_store(entry))
+ {
+ // get block start/end blocks for this block
+ offs_t blockstart = entry->m_bytestart / MEMORY_BLOCK_CHUNK;
+ offs_t blockend = entry->m_byteend / MEMORY_BLOCK_CHUNK;
- /* 8-bit case: RAM/ROM */
- if (entry >= STATIC_RAM)
- return NULL;
- byteoffset = (byteaddress - handler->bytestart) & handler->bytemask;
- return &(*handler->bankbaseptr)[byteoffset];
-}
+ // if we intersect or are adjacent, adjust the start/end
+ if (blockstart <= curblockend + 1 && blockend >= curblockstart - 1)
+ {
+ if (blockstart < curblockstart)
+ curblockstart = blockstart, changed = true;
+ if (blockend > curblockend)
+ curblockend = blockend, changed = true;
+ }
+ }
+ } while (changed);
+ // we now have a block to allocate; do it
+ offs_t curbytestart = curblockstart * MEMORY_BLOCK_CHUNK;
+ offs_t curbyteend = curblockend * MEMORY_BLOCK_CHUNK + (MEMORY_BLOCK_CHUNK - 1);
+ memory_block &block = blocklist.append(*auto_alloc(&m_machine, memory_block(*this, curbytestart, curbyteend)));
+ // assign memory that intersected the new block
+ unassigned = block_assign_intersecting(curbytestart, curbyteend, block.data());
+ }
+}
-/***************************************************************************
- MEMORY BANKING
-***************************************************************************/
-/*-------------------------------------------------
- memory_configure_bank - configure the
- addresses for a bank
--------------------------------------------------*/
+//-------------------------------------------------
+// locate_memory - find all the requested
+// pointers into the final allocated memory
+//-------------------------------------------------
-void memory_configure_bank(running_machine *machine, const char *tag, int startentry, int numentries, void *base, offs_t stride)
+void address_space::locate_memory()
{
- memory_private *memdata = machine->memory_data;
- bank_info *bank = memdata->bankmap.find_hash_only(tag);
- int entrynum;
-
- /* validation checks */
- if (bank == NULL)
- fatalerror("memory_configure_bank called for unknown bank '%s'", tag);
- if (startentry < 0 || startentry + numentries > MAX_BANK_ENTRIES)
- fatalerror("memory_configure_bank called with out-of-range entries %d-%d", startentry, startentry + numentries - 1);
- if (!base)
- fatalerror("memory_configure_bank called NULL base");
+ // fill in base/size entries
+ for (const address_map_entry *entry = m_map->m_entrylist.first(); entry != NULL; entry = entry->next())
+ {
+ if (entry->m_baseptr != NULL)
+ *entry->m_baseptr = entry->m_memory;
+ if (entry->m_baseptroffs_plus1 != 0)
+ *(void **)(reinterpret_cast<UINT8 *>(m_machine.driver_data<void>()) + entry->m_baseptroffs_plus1 - 1) = entry->m_memory;
+ if (entry->m_genbaseptroffs_plus1 != 0)
+ *(void **)((UINT8 *)&m_machine.generic + entry->m_genbaseptroffs_plus1 - 1) = entry->m_memory;
+ if (entry->m_sizeptr != NULL)
+ *entry->m_sizeptr = entry->m_byteend - entry->m_bytestart + 1;
+ if (entry->m_sizeptroffs_plus1 != 0)
+ *(size_t *)(reinterpret_cast<UINT8 *>(m_machine.driver_data<void>()) + entry->m_sizeptroffs_plus1 - 1) = entry->m_byteend - entry->m_bytestart + 1;
+ if (entry->m_gensizeptroffs_plus1 != 0)
+ *(size_t *)((UINT8 *)&m_machine.generic + entry->m_gensizeptroffs_plus1 - 1) = entry->m_byteend - entry->m_bytestart + 1;
+ }
- /* fill in the requested bank entries */
- for (entrynum = startentry; entrynum < startentry + numentries; entrynum++)
- bank->entry[entrynum] = (UINT8 *)base + (entrynum - startentry) * stride;
+ // once this is done, find the starting bases for the banks
+ for (memory_bank *bank = m_machine.memory_data->banklist.first(); bank != NULL; bank = bank->next())
+ if (bank->base() == NULL && bank->references_space(*this, ROW_READWRITE))
+ {
+ // set the initial bank pointer
+ for (address_map_entry *entry = m_map->m_entrylist.first(); entry != NULL; entry = entry->next())
+ if (entry->m_bytestart == bank->bytestart() && entry->m_memory != NULL)
+ {
+ bank->set_base(entry->m_memory);
+ VPRINTF(("assigned bank '%s' pointer to memory from range %08X-%08X [%p]\n", bank->tag(), entry->m_addrstart, entry->m_addrend, entry->m_memory));
+ break;
+ }
- /* if we have no bankptr yet, set it to the first entry */
- if (memdata->bank_ptr[bank->index] == NULL)
- memdata->bank_ptr[bank->index] = (UINT8 *)bank->entry[0];
+ // if the entry was set ahead of time, override the automatically found pointer
+ if (!bank->anonymous() && bank->entry() != BANK_ENTRY_UNSPECIFIED)
+ bank->set_entry(bank->entry());
+ }
}
-/*-------------------------------------------------
- memory_configure_bank_decrypted - configure
- the decrypted addresses for a bank
--------------------------------------------------*/
+//-------------------------------------------------
+// set_decrypted_region - registers an address
+// range as having a decrypted data pointer
+//-------------------------------------------------
-void memory_configure_bank_decrypted(running_machine *machine, const char *tag, int startentry, int numentries, void *base, offs_t stride)
+void address_space::set_decrypted_region(offs_t addrstart, offs_t addrend, void *base)
{
- memory_private *memdata = machine->memory_data;
- bank_info *bank = memdata->bankmap.find_hash_only(tag);
- int entrynum;
+ offs_t bytestart = address_to_byte(addrstart);
+ offs_t byteend = address_to_byte_end(addrend);
+ bool found = false;
- /* validation checks */
- if (bank == NULL)
- fatalerror("memory_configure_bank_decrypted called for unknown bank '%s'", tag);
- if (startentry < 0 || startentry + numentries > MAX_BANK_ENTRIES)
- fatalerror("memory_configure_bank_decrypted called with out-of-range entries %d-%d", startentry, startentry + numentries - 1);
- if (!base)
- fatalerror("memory_configure_bank_decrypted called NULL base");
+ // loop over banks looking for a match
+ for (memory_bank *bank = m_machine.memory_data->banklist.first(); bank != NULL; bank = bank->next())
+ {
+ // consider this bank if it is used for reading and matches the address space
+ if (bank->references_space(*this, ROW_READ))
+ {
+ // verify that the region fully covers the decrypted range
+ if (bank->fully_covers(bytestart, byteend))
+ {
+ // set the decrypted pointer for the corresponding memory bank
+ bank->set_base_decrypted(reinterpret_cast<UINT8 *>(base) + bank->bytestart() - bytestart);
+ found = true;
+ }
- /* fill in the requested bank entries */
- for (entrynum = startentry; entrynum < startentry + numentries; entrynum++)
- bank->entryd[entrynum] = (UINT8 *)base + (entrynum - startentry) * stride;
+ // fatal error if the decrypted region straddles the bank
+ else if (bank->partially_covers(bytestart, byteend))
+ throw emu_fatalerror("memory_set_decrypted_region found straddled region %08X-%08X for device '%s'", bytestart, byteend, m_device.tag());
+ }
+ }
- /* if we have no bankptr yet, set it to the first entry */
- if (memdata->bankd_ptr[bank->index] == NULL)
- memdata->bankd_ptr[bank->index] = (UINT8 *)bank->entryd[0];
+ // fatal error as well if we didn't find any relevant memory banks
+ if (!found)
+ throw emu_fatalerror("memory_set_decrypted_region unable to find matching region %08X-%08X for device '%s'", bytestart, byteend, m_device.tag());
}
-/*-------------------------------------------------
- memory_set_bank - select one pre-configured
- entry to be the new bank base
--------------------------------------------------*/
+//-------------------------------------------------
+// block_assign_intersecting - find all
+// intersecting blocks and assign their pointers
+//-------------------------------------------------
-void memory_set_bank(running_machine *machine, const char *tag, int entrynum)
+address_map_entry *address_space::block_assign_intersecting(offs_t bytestart, offs_t byteend, UINT8 *base)
{
- memory_private *memdata = machine->memory_data;
- bank_info *bank = memdata->bankmap.find_hash_only(tag);
- bank_reference *ref;
+ memory_private *memdata = m_machine.memory_data;
+ address_map_entry *unassigned = NULL;
- /* validation checks */
- if (bank == NULL)
- fatalerror("memory_set_bank called for unknown bank '%s'", tag);
- if (entrynum < 0 || entrynum > MAX_BANK_ENTRIES)
- fatalerror("memory_set_bank called with out-of-range entry %d", entrynum);
- if (!bank->entry[entrynum])
- fatalerror("memory_set_bank called for bank '%s' with invalid bank entry %d", tag, entrynum);
+ // loop over the adjusted map and assign memory to any blocks we can
+ for (address_map_entry *entry = m_map->m_entrylist.first(); entry != NULL; entry = entry->next())
+ {
+ // if we haven't assigned this block yet, see if we have a mapped shared pointer for it
+ if (entry->m_memory == NULL && entry->m_share != NULL)
+ {
+ void *shareptr = memdata->sharemap.find(entry->m_share);
+ if (shareptr != UNMAPPED_SHARE_PTR)
+ {
+ entry->m_memory = shareptr;
+ VPRINTF(("memory range %08X-%08X -> shared_ptr '%s' [%p]\n", entry->m_addrstart, entry->m_addrend, entry->m_share, entry->m_memory));
+ }
+ }
+
+ // otherwise, look for a match in this block
+ if (entry->m_memory == NULL && entry->m_bytestart >= bytestart && entry->m_byteend <= byteend)
+ {
+ entry->m_memory = base + (entry->m_bytestart - bytestart);
+ VPRINTF(("memory range %08X-%08X -> found in block from %08X-%08X [%p]\n", entry->m_addrstart, entry->m_addrend, bytestart, byteend, entry->m_memory));
+ }
+
+ // if we're the first match on a shared pointer, assign it now
+ if (entry->m_memory != NULL && entry->m_share != NULL)
+ {
+ void *shareptr = memdata->sharemap.find(entry->m_share);
+ if (shareptr == UNMAPPED_SHARE_PTR)
+ memdata->sharemap.add(entry->m_share, entry->m_memory, TRUE);
+ }
- /* set the base */
- bank->curentry = entrynum;
- memdata->bank_ptr[bank->index] = (UINT8 *)bank->entry[entrynum];
- memdata->bankd_ptr[bank->index] = (UINT8 *)bank->entryd[entrynum];
+ // keep track of the first unassigned entry
+ if (entry->m_memory == NULL && unassigned == NULL && needs_backing_store(entry))
+ unassigned = entry;
+ }
- /* invalidate all the direct references to any referenced address spaces */
- for (ref = bank->reflist; ref != NULL; ref = ref->next)
- force_opbase_update(ref->space);
+ return unassigned;
}
-/*-------------------------------------------------
- memory_get_bank - return the currently
- selected bank
--------------------------------------------------*/
+//-------------------------------------------------
+// get_handler_string - return a string
+// describing the handler at a particular offset
+//-------------------------------------------------
-int memory_get_bank(running_machine *machine, const char *tag)
+const char *address_space::get_handler_string(read_or_write readorwrite, offs_t byteaddress)
{
- memory_private *memdata = machine->memory_data;
- bank_info *bank = memdata->bankmap.find_hash_only(tag);
-
- /* validation checks */
- if (bank == NULL)
- fatalerror("memory_get_bank called for unknown bank '%s'", tag);
- return bank->curentry;
+ if (readorwrite == ROW_READ)
+ return read().handler_name(read().lookup(byteaddress));
+ else
+ return write().handler_name(write().lookup(byteaddress));
}
-/*-------------------------------------------------
- memory_set_bankptr - set the base of a bank
--------------------------------------------------*/
+//-------------------------------------------------
+// dump_map - dump the contents of a single
+// address space
+//-------------------------------------------------
-void memory_set_bankptr(running_machine *machine, const char *tag, void *base)
+void address_space::dump_map(FILE *file, read_or_write readorwrite)
{
- memory_private *memdata = machine->memory_data;
- bank_info *bank = memdata->bankmap.find_hash_only(tag);
- bank_reference *ref;
-
- /* validation checks */
- if (bank == NULL)
- fatalerror("memory_set_bankptr called for unknown bank '%s'", tag);
- if (base == NULL)
- fatalerror("memory_set_bankptr called NULL base");
-// if (ALLOW_ONLY_AUTO_MALLOC_BANKS)
-// validate_auto_malloc_memory(base, bank->byteend - bank->bytestart + 1);
+ const address_table &table = (readorwrite == ROW_READ) ? static_cast<address_table &>(read()) : static_cast<address_table &>(write());
- /* set the base */
- memdata->bank_ptr[bank->index] = (UINT8 *)base;
+ // dump generic information
+ fprintf(file, " Address bits = %d\n", m_config.m_addrbus_width);
+ fprintf(file, " Data bits = %d\n", m_config.m_databus_width);
+ fprintf(file, " Address mask = %X\n", m_bytemask);
+ fprintf(file, "\n");
- /* invalidate all the direct references to any referenced address spaces */
- for (ref = bank->reflist; ref != NULL; ref = ref->next)
- force_opbase_update(ref->space);
+ // iterate over addresses
+ offs_t bytestart, byteend;
+ for (offs_t byteaddress = 0; byteaddress <= m_bytemask; byteaddress = byteend)
+ {
+ UINT8 entry = table.derive_range(byteaddress, bytestart, byteend);
+ fprintf(file, "%08X-%08X = %02X: %s [offset=%08X]\n",
+ bytestart, byteend, entry, table.handler_name(entry), table.handler(entry).bytestart());
+ if (++byteend == 0)
+ break;
+ }
}
+//**************************************************************************
+// DYNAMIC ADDRESS SPACE MAPPING
+//**************************************************************************
-/***************************************************************************
- DYNAMIC ADDRESS SPACE MAPPING
-***************************************************************************/
-
-/*-------------------------------------------------
- _memory_install_handler - install a new memory
- handler into the given address space,
- returning a pointer to the memory backing it,
- if present
--------------------------------------------------*/
-
-#ifdef UNUSED_CODE
-void *_memory_install_handler(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, FPTR rhandler, FPTR whandler)
-{
- address_space *spacerw = (address_space *)space;
- if (rhandler >= STATIC_COUNT)
- fatalerror("Attempted to install non-static read handler via memory_install_handler() in space %s of device '%s'\n", space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (whandler >= STATIC_COUNT)
- fatalerror("Attempted to install non-static write handler via memory_install_handler() in space %s of device '%s'\n", space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (rhandler != 0)
- space_map_range(spacerw, ROW_READ, spacerw->dbits, 0, addrstart, addrend, addrmask, addrmirror, (genf *)(FPTR)rhandler, spacerw, NULL);
- if (whandler != 0)
- space_map_range(spacerw, ROW_WRITE, spacerw->dbits, 0, addrstart, addrend, addrmask, addrmirror, (genf *)(FPTR)whandler, spacerw, NULL);
- mem_dump(space->machine);
- return space_find_backing_memory(spacerw, addrstart, addrend);
-}
-#endif
-
-
-/*-------------------------------------------------
- _memory_install_handler8 - same as above but
- explicitly for 8-bit handlers
--------------------------------------------------*/
-
-UINT8 *_memory_install_handler8(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_space_func rhandler, const char *rhandler_name, write8_space_func whandler, const char *whandler_name, int handlerunitmask)
-{
- address_space *spacerw = (address_space *)space;
- if (rhandler != NULL && (FPTR)rhandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid read handler in space %s of device '%s'\n", space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (whandler != NULL && (FPTR)whandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid write handler in space %s of device '%s'\n", space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (rhandler != NULL)
- space_map_range(spacerw, ROW_READ, 8, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)rhandler, spacerw, rhandler_name);
- if (whandler != NULL)
- space_map_range(spacerw, ROW_WRITE, 8, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)whandler, spacerw, whandler_name);
- mem_dump(space->machine);
- return (UINT8 *)space_find_backing_memory(spacerw, addrstart, addrend);
-}
-
-
-/*-------------------------------------------------
- _memory_install_handler16 - same as above but
- explicitly for 16-bit handlers
--------------------------------------------------*/
-
-UINT16 *_memory_install_handler16(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_space_func rhandler, const char *rhandler_name, write16_space_func whandler, const char *whandler_name, int handlerunitmask)
-{
- address_space *spacerw = (address_space *)space;
- if (rhandler != NULL && (FPTR)rhandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid read handler in space %s of device '%s'\n", space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (whandler != NULL && (FPTR)whandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid write handler in space %s of device '%s'\n", space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (rhandler != NULL)
- space_map_range(spacerw, ROW_READ, 16, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)rhandler, spacerw, rhandler_name);
- if (whandler != NULL)
- space_map_range(spacerw, ROW_WRITE, 16, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)whandler, spacerw, whandler_name);
- mem_dump(space->machine);
- return (UINT16 *)space_find_backing_memory(spacerw, addrstart, addrend);
-}
-
-
-/*-------------------------------------------------
- _memory_install_handler32 - same as above but
- explicitly for 32-bit handlers
--------------------------------------------------*/
-
-UINT32 *_memory_install_handler32(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_space_func rhandler, const char *rhandler_name, write32_space_func whandler, const char *whandler_name, int handlerunitmask)
-{
- address_space *spacerw = (address_space *)space;
- if (rhandler != NULL && (FPTR)rhandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid read handler in space %s of device '%s'\n", space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (whandler != NULL && (FPTR)whandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid write handler in space %s of device '%s'\n", space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (rhandler != NULL)
- space_map_range(spacerw, ROW_READ, 32, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)rhandler, spacerw, rhandler_name);
- if (whandler != NULL)
- space_map_range(spacerw, ROW_WRITE, 32, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)whandler, spacerw, whandler_name);
- mem_dump(space->machine);
- return (UINT32 *)space_find_backing_memory(spacerw, addrstart, addrend);
-}
-
-
-/*-------------------------------------------------
- _memory_install_handler64 - same as above but
- explicitly for 64-bit handlers
--------------------------------------------------*/
-
-UINT64 *_memory_install_handler64(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_space_func rhandler, const char *rhandler_name, write64_space_func whandler, const char *whandler_name, int handlerunitmask)
-{
- address_space *spacerw = (address_space *)space;
- if (rhandler != NULL && (FPTR)rhandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid read handler in space %s of device '%s'\n", space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (whandler != NULL && (FPTR)whandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid write handler in space %s of device '%s'\n", space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (rhandler != NULL)
- space_map_range(spacerw, ROW_READ, 64, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)rhandler, spacerw, rhandler_name);
- if (whandler != NULL)
- space_map_range(spacerw, ROW_WRITE, 64, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)whandler, spacerw, whandler_name);
- mem_dump(space->machine);
- return (UINT64 *)space_find_backing_memory(spacerw, addrstart, addrend);
-}
-
-
-/*-------------------------------------------------
- _memory_install_device_handler8 - same as above
- but explicitly for 8-bit handlers
--------------------------------------------------*/
-
-UINT8 *_memory_install_device_handler8(const address_space *space, device_t *device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_device_func rhandler, const char *rhandler_name, write8_device_func whandler, const char *whandler_name, int handlerunitmask)
-{
- address_space *spacerw = (address_space *)space;
- if (rhandler != NULL && (FPTR)rhandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid read handler for device '%s' in space %s of device '%s'\n", device->tag(), space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (whandler != NULL && (FPTR)whandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid write handler for device '%s' in space %s of device '%s'\n", device->tag(), space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (rhandler != NULL)
- space_map_range(spacerw, ROW_READ, 8, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)rhandler, (void *)device, rhandler_name);
- if (whandler != NULL)
- space_map_range(spacerw, ROW_WRITE, 8, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)whandler, (void *)device, whandler_name);
- mem_dump(space->machine);
- return (UINT8 *)space_find_backing_memory(spacerw, addrstart, addrend);
-}
-
-
-/*-------------------------------------------------
- _memory_install_device_handler16 - same as
- above but explicitly for 16-bit handlers
--------------------------------------------------*/
-
-UINT16 *_memory_install_device_handler16(const address_space *space, device_t *device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_device_func rhandler, const char *rhandler_name, write16_device_func whandler, const char *whandler_name, int handlerunitmask)
-{
- address_space *spacerw = (address_space *)space;
- if (rhandler != NULL && (FPTR)rhandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid read handler for device '%s' in space %s of device '%s'\n", device->tag(), space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (whandler != NULL && (FPTR)whandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid write handler for device '%s' in space %s of device '%s'\n", device->tag(), space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (rhandler != NULL)
- space_map_range(spacerw, ROW_READ, 16, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)rhandler, (void *)device, rhandler_name);
- if (whandler != NULL)
- space_map_range(spacerw, ROW_WRITE, 16, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)whandler, (void *)device, whandler_name);
- mem_dump(space->machine);
- return (UINT16 *)space_find_backing_memory(spacerw, addrstart, addrend);
-}
-
-
-/*-------------------------------------------------
- _memory_install_device_handler32 - same as
- above but explicitly for 32-bit handlers
--------------------------------------------------*/
-
-UINT32 *_memory_install_device_handler32(const address_space *space, device_t *device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_device_func rhandler, const char *rhandler_name, write32_device_func whandler, const char *whandler_name, int handlerunitmask)
-{
- address_space *spacerw = (address_space *)space;
- if (rhandler != NULL && (FPTR)rhandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid read handler for device '%s' in space %s of device '%s'\n", device->tag(), space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (whandler != NULL && (FPTR)whandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid write handler for device '%s' in space %s of device '%s'\n", device->tag(), space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (rhandler != NULL)
- space_map_range(spacerw, ROW_READ, 32, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)rhandler, (void *)device, rhandler_name);
- if (whandler != NULL)
- space_map_range(spacerw, ROW_WRITE, 32, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)whandler, (void *)device, whandler_name);
- mem_dump(space->machine);
- return (UINT32 *)space_find_backing_memory(spacerw, addrstart, addrend);
-}
-
+//-------------------------------------------------
+// unmap - unmap a section of address space
+//-------------------------------------------------
-/*-------------------------------------------------
- _memory_install_device_handler64 - same as
- above but explicitly for 64-bit handlers
--------------------------------------------------*/
-
-UINT64 *_memory_install_device_handler64(const address_space *space, device_t *device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_device_func rhandler, const char *rhandler_name, write64_device_func whandler, const char *whandler_name, int handlerunitmask)
-{
- address_space *spacerw = (address_space *)space;
- if (rhandler != NULL && (FPTR)rhandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid read handler for device '%s' in space %s of device '%s'\n", device->tag(), space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (whandler != NULL && (FPTR)whandler < STATIC_COUNT)
- fatalerror("Attempted to install invalid write handler for device '%s' in space %s of device '%s'\n", device->tag(), space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- if (rhandler != NULL)
- space_map_range(spacerw, ROW_READ, 64, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)rhandler, (void *)device, rhandler_name);
- if (whandler != NULL)
- space_map_range(spacerw, ROW_WRITE, 64, handlerunitmask, addrstart, addrend, addrmask, addrmirror, (genf *)whandler, (void *)device, whandler_name);
- mem_dump(space->machine);
- return (UINT64 *)space_find_backing_memory(spacerw, addrstart, addrend);
-}
+void address_space::unmap(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read_or_write readorwrite, bool quiet)
+{
+ // read space
+ if (readorwrite == ROW_READ || readorwrite == ROW_READWRITE)
+ read().map_range(addrstart, addrend, addrmask, addrmirror, quiet ? STATIC_NOP : STATIC_UNMAP);
+ // write space
+ if (readorwrite == ROW_WRITE || readorwrite == ROW_READWRITE)
+ write().map_range(addrstart, addrend, addrmask, addrmirror, quiet ? STATIC_NOP : STATIC_UNMAP);
+}
-/*-------------------------------------------------
- _memory_install_port - install a
- new port handler into the given address space
--------------------------------------------------*/
-
-void _memory_install_port(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, const char *rtag, const char *wtag)
-{
- address_space *spacerw = (address_space *)space;
- genf *rhandler = NULL;
- genf *whandler = NULL;
- /* pick the appropriate read/write handlers */
- switch (space->dbits)
- {
- case 8: rhandler = (genf *)input_port_read8; whandler = (genf *)input_port_write8; break;
- case 16: rhandler = (genf *)input_port_read16; whandler = (genf *)input_port_write16; break;
- case 32: rhandler = (genf *)input_port_read32; whandler = (genf *)input_port_write32; break;
- case 64: rhandler = (genf *)input_port_read64; whandler = (genf *)input_port_write64; break;
- }
+//-------------------------------------------------
+// install_port - install a new I/O port handler
+// into this address space
+//-------------------------------------------------
- /* assign the read handler */
+void address_space::install_port(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, const char *rtag, const char *wtag)
+{
+ // read handler
if (rtag != NULL)
{
- const input_port_config *port = space->machine->port(rtag);
+ // find the port
+ const input_port_config *port = m_machine.port(rtag);
if (port == NULL)
- fatalerror("Attempted to map non-existent port '%s' for read in space %s of device '%s'\n", rtag, space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- space_map_range(spacerw, ROW_READ, space->dbits, 0, addrstart, addrend, addrmask, addrmirror, rhandler, (void *)port, rtag);
+ throw emu_fatalerror("Attempted to map non-existent port '%s' for read in space %s of device '%s'\n", rtag, m_name, m_device.tag());
+
+ // map the range and set the ioport
+ UINT32 entry = read().map_range(addrstart, addrend, addrmask, addrmirror);
+ read().handler_read(entry).set_ioport(*port);
}
- /* assign the write handler */
if (wtag != NULL)
{
- const input_port_config *port = space->machine->port(wtag);
+ // find the port
+ const input_port_config *port = m_machine.port(wtag);
if (port == NULL)
- fatalerror("Attempted to map non-existent port '%s' for write in space %s of device '%s'\n", wtag, space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- space_map_range(spacerw, ROW_WRITE, space->dbits, 0, addrstart, addrend, addrmask, addrmirror, whandler, (void *)port, wtag);
+ fatalerror("Attempted to map non-existent port '%s' for write in space %s of device '%s'\n", wtag, m_name, m_device.tag());
+
+ // map the range and set the ioport
+ UINT32 entry = write().map_range(addrstart, addrend, addrmask, addrmirror);
+ write().handler_write(entry).set_ioport(*port);
}
- /* update the memory dump */
- mem_dump(space->machine);
+ // update the memory dump
+ generate_memdump(&m_machine);
}
-/*-------------------------------------------------
- _memory_install_bank - install a
- new port handler into the given address space
--------------------------------------------------*/
+//-------------------------------------------------
+// install_bank - install a range as mapping to
+// a particular bank
+//-------------------------------------------------
-void _memory_install_bank(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, const char *rtag, const char *wtag)
+void address_space::install_bank(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, const char *rtag, const char *wtag)
{
- address_space *spacerw = (address_space *)space;
-
- /* map the read bank */
+ // map the read bank
if (rtag != NULL)
{
- genf *handler = bank_find_or_allocate(space, rtag, addrstart, addrend, addrmask, addrmirror, ROW_READ);
- space_map_range(spacerw, ROW_READ, space->dbits, 0, addrstart, addrend, addrmask, addrmirror, handler, spacerw, rtag);
+ memory_bank &bank = bank_find_or_allocate(rtag, addrstart, addrend, addrmask, addrmirror, ROW_READ);
+ read().map_range(addrstart, addrend, addrmask, addrmirror, bank.index());
}
- /* map the write bank */
+ // map the write bank
if (wtag != NULL)
{
- genf *handler = bank_find_or_allocate(space, wtag, addrstart, addrend, addrmask, addrmirror, ROW_WRITE);
- space_map_range(spacerw, ROW_WRITE, space->dbits, 0, addrstart, addrend, addrmask, addrmirror, handler, spacerw, wtag);
+ memory_bank &bank = bank_find_or_allocate(wtag, addrstart, addrend, addrmask, addrmirror, ROW_WRITE);
+ write().map_range(addrstart, addrend, addrmask, addrmirror, bank.index());
}
- /* update the memory dump */
- mem_dump(space->machine);
+ // update the memory dump
+ generate_memdump(&m_machine);
}
-/*-------------------------------------------------
- _memory_install_ram - install a simple fixed
- RAM region into the given address space
--------------------------------------------------*/
+//-------------------------------------------------
+// install_ram - install a simple fixed RAM
+// region into the given address space
+//-------------------------------------------------
-void *_memory_install_ram(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, UINT8 install_read, UINT8 install_write, void *baseptr)
+void *address_space::install_ram(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read_or_write readorwrite, void *baseptr)
{
- memory_private *memdata = space->machine->memory_data;
- address_space *spacerw = (address_space *)space;
- FPTR bankindex;
- genf *handler;
+ memory_private *memdata = m_machine.memory_data;
- /* map for read */
- if (install_read)
+ // map for read
+ if (readorwrite == ROW_READ || readorwrite == ROW_READWRITE)
{
- handler = bank_find_or_allocate(space, NULL, addrstart, addrend, addrmask, addrmirror, ROW_READ);
- space_map_range(spacerw, ROW_READ, space->dbits, 0, addrstart, addrend, addrmask, addrmirror, handler, spacerw, "ram");
+ // find a bank and map it
+ memory_bank &bank = bank_find_or_allocate(NULL, addrstart, addrend, addrmask, addrmirror, ROW_READ);
+ read().map_range(addrstart, addrend, addrmask, addrmirror, bank.index());
- /* if we are provided a pointer, set it */
- bankindex = (FPTR)handler;
+ // if we are provided a pointer, set it
if (baseptr != NULL)
- memdata->bank_ptr[bankindex] = (UINT8 *)baseptr;
+ bank.set_base(baseptr);
- /* if we don't have a bank pointer yet, try to find one */
- if (memdata->bank_ptr[bankindex] == NULL)
- memdata->bank_ptr[bankindex] = (UINT8 *)space_find_backing_memory(space, addrstart, addrend);
+ // if we don't have a bank pointer yet, try to find one
+ if (bank.base() == NULL)
+ {
+ void *backing = find_backing_memory(addrstart, addrend);
+ if (backing != NULL)
+ bank.set_base(backing);
+ }
- /* if we still don't have a pointer, and we're past the initialization phase, allocate a new block */
- if (memdata->bank_ptr[bankindex] == NULL && memdata->initialized)
+ // if we still don't have a pointer, and we're past the initialization phase, allocate a new block
+ if (bank.base() == NULL && memdata->initialized)
{
- if (space->machine->phase() >= MACHINE_PHASE_RESET)
+ if (m_machine.phase() >= MACHINE_PHASE_RESET)
fatalerror("Attempted to call memory_install_ram() after initialization time without a baseptr!");
- memdata->bank_ptr[bankindex] = (UINT8 *)block_allocate(space, memory_address_to_byte(space, addrstart), memory_address_to_byte_end(space, addrend), NULL);
+ memory_block &block = memdata->blocklist.append(*auto_alloc(&m_machine, memory_block(*this, address_to_byte(addrstart), address_to_byte_end(addrend))));
+ bank.set_base(block.data());
}
}
- /* map for write */
- if (install_write)
+ // map for write
+ if (readorwrite == ROW_WRITE || readorwrite == ROW_READWRITE)
{
- handler = bank_find_or_allocate(space, NULL, addrstart, addrend, addrmask, addrmirror, ROW_WRITE);
- space_map_range(spacerw, ROW_WRITE, space->dbits, 0, addrstart, addrend, addrmask, addrmirror, handler, spacerw, "ram");
+ // find a bank and map it
+ memory_bank &bank = bank_find_or_allocate(NULL, addrstart, addrend, addrmask, addrmirror, ROW_WRITE);
+ write().map_range(addrstart, addrend, addrmask, addrmirror, bank.index());
- /* if we are provided a pointer, set it */
- bankindex = (FPTR)handler;
+ // if we are provided a pointer, set it
if (baseptr != NULL)
- memdata->bank_ptr[bankindex] = (UINT8 *)baseptr;
+ bank.set_base(baseptr);
- /* if we don't have a bank pointer yet, try to find one */
- if (memdata->bank_ptr[bankindex] == NULL)
- memdata->bank_ptr[bankindex] = (UINT8 *)space_find_backing_memory(space, addrstart, addrend);
+ // if we don't have a bank pointer yet, try to find one
+ if (bank.base() == NULL)
+ {
+ void *backing = find_backing_memory(addrstart, addrend);
+ if (backing != NULL)
+ bank.set_base(backing);
+ }
- /* if we still don't have a pointer, and we're past the initialization phase, allocate a new block */
- if (memdata->bank_ptr[bankindex] == NULL && memdata->initialized)
+ // if we still don't have a pointer, and we're past the initialization phase, allocate a new block
+ if (bank.base() == NULL && memdata->initialized)
{
- if (space->machine->phase() >= MACHINE_PHASE_RESET)
+ if (m_machine.phase() >= MACHINE_PHASE_RESET)
fatalerror("Attempted to call memory_install_ram() after initialization time without a baseptr!");
- memdata->bank_ptr[bankindex] = (UINT8 *)block_allocate(space, memory_address_to_byte(space, addrstart), memory_address_to_byte_end(space, addrend), NULL);
+ memory_block &block = memdata->blocklist.append(*auto_alloc(&m_machine, memory_block(*this, address_to_byte(addrstart), address_to_byte_end(addrend))));
+ bank.set_base(block.data());
}
}
- return (void *)space_find_backing_memory(spacerw, addrstart, addrend);
+ return (void *)find_backing_memory(addrstart, addrend);
}
-/*-------------------------------------------------
- _memory_unmap - unmap a section of address
- space
--------------------------------------------------*/
+//-------------------------------------------------
+// install_handler - install 8-bit read/write
+// delegate handlers for the space
+//-------------------------------------------------
-void _memory_unmap(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, UINT8 unmap_read, UINT8 unmap_write, UINT8 quiet)
+UINT8 *address_space::install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_delegate handler, UINT64 unitmask)
{
- address_space *spacerw = (address_space *)space;
-
- if (unmap_read)
- space_map_range(spacerw, ROW_READ, space->dbits, 0, addrstart, addrend, addrmask, addrmirror, (genf *)(FPTR)(quiet ? STATIC_NOP : STATIC_UNMAP), spacerw, "unmapped");
- if (unmap_write)
- space_map_range(spacerw, ROW_WRITE, space->dbits, 0, addrstart, addrend, addrmask, addrmirror, (genf *)(FPTR)(quiet ? STATIC_NOP : STATIC_UNMAP), spacerw, "unmapped");
+ UINT32 entry = read().map_range(addrstart, addrend, addrmask, addrmirror);
+ read().handler_read(entry).set_delegate(handler, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT8 *>(find_backing_memory(addrstart, addrend));
}
-
-
-/***************************************************************************
- DEBUGGER HELPERS
-***************************************************************************/
-
-/*-------------------------------------------------
- memory_get_handler_string - return a string
- describing the handler at a particular offset
--------------------------------------------------*/
-
-const char *memory_get_handler_string(const address_space *space, int read0_or_write1, offs_t byteaddress)
+UINT8 *address_space::install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write8_delegate handler, UINT64 unitmask)
{
- const address_table *table = read0_or_write1 ? &space->write : &space->read;
- UINT8 entry;
-
- /* perform the lookup */
- byteaddress &= space->bytemask;
- entry = table->table[LEVEL1_INDEX(byteaddress)];
- if (entry >= SUBTABLE_BASE)
- entry = table->table[LEVEL2_INDEX(entry, byteaddress)];
-
- /* 8-bit case: RAM/ROM */
- return handler_to_string(space, table, entry);
+ UINT32 entry = write().map_range(addrstart, addrend, addrmask, addrmirror);
+ write().handler_write(entry).set_delegate(handler, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT8 *>(find_backing_memory(addrstart, addrend));
}
-
-/*-------------------------------------------------
- memory_enable_read_watchpoints - enable/disable
- read watchpoint tracking for a given address
- space
--------------------------------------------------*/
-
-void memory_enable_read_watchpoints(const address_space *space, int enable)
+UINT8 *address_space::install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_delegate rhandler, write8_delegate whandler, UINT64 unitmask)
{
- address_space *spacerw = (address_space *)space;
- if (enable)
- spacerw->readlookup = space->machine->memory_data->wptable;
- else
- spacerw->readlookup = spacerw->read.table;
+ install_handler(addrstart, addrend, addrmask, addrmirror, rhandler, unitmask);
+ return install_handler(addrstart, addrend, addrmask, addrmirror, whandler, unitmask);
}
-/*-------------------------------------------------
- memory_enable_write_watchpoints - enable/disable
- write watchpoint tracking for a given address
- space
--------------------------------------------------*/
+//-------------------------------------------------
+// install_legacy_handler - install 8-bit read/
+// write legacy address space handlers for the
+// space
+//-------------------------------------------------
-void memory_enable_write_watchpoints(const address_space *space, int enable)
+UINT8 *address_space::install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_space_func rhandler, const char *rname, UINT64 unitmask)
{
- address_space *spacerw = (address_space *)space;
- if (enable)
- spacerw->writelookup = space->machine->memory_data->wptable;
- else
- spacerw->writelookup = spacerw->write.table;
+ UINT32 entry = read().map_range(addrstart, addrend, addrmask, addrmirror);
+ read().handler_read(entry).set_legacy_func(*this, rhandler, rname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT8 *>(find_backing_memory(addrstart, addrend));
}
-
-/*-------------------------------------------------
- memory_set_debugger_access - control whether
- subsequent accesses are treated as coming from
- the debugger
--------------------------------------------------*/
-
-void memory_set_debugger_access(const address_space *space, int debugger)
+UINT8 *address_space::install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write8_space_func whandler, const char *wname, UINT64 unitmask)
{
- address_space *spacerw = (address_space *)space;
- spacerw->debugger_access = debugger;
+ UINT32 entry = write().map_range(addrstart, addrend, addrmask, addrmirror);
+ write().handler_write(entry).set_legacy_func(*this, whandler, wname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT8 *>(find_backing_memory(addrstart, addrend));
}
-
-/*-------------------------------------------------
- memory_set_log_unmap - sets whether unmapped
- memory accesses should be logged or not
--------------------------------------------------*/
-
-void memory_set_log_unmap(const address_space *space, int log)
+UINT8 *address_space::install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_space_func rhandler, const char *rname, write8_space_func whandler, const char *wname, UINT64 unitmask)
{
- address_space *spacerw = (address_space *)space;
- spacerw->log_unmap = log;
+ install_legacy_handler(addrstart, addrend, addrmask, addrmirror, rhandler, rname, unitmask);
+ return install_legacy_handler(addrstart, addrend, addrmask, addrmirror, whandler, wname, unitmask);
}
-/*-------------------------------------------------
- memory_get_log_unmap - gets whether unmapped
- memory accesses should be logged or not
--------------------------------------------------*/
+//-------------------------------------------------
+// install_legacy_handler - install 8-bit read/
+// write legacy device handlers for the space
+//-------------------------------------------------
-int memory_get_log_unmap(const address_space *space)
+UINT8 *address_space::install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_device_func rhandler, const char *rname, UINT64 unitmask)
{
- return space->log_unmap;
+ UINT32 entry = read().map_range(addrstart, addrend, addrmask, addrmirror);
+ read().handler_read(entry).set_legacy_func(device, rhandler, rname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT8 *>(find_backing_memory(addrstart, addrend));
}
-
-/*-------------------------------------------------
- memory_dump - dump the internal memory tables
- to the given file
--------------------------------------------------*/
-
-void memory_dump(running_machine *machine, FILE *file)
+UINT8 *address_space::install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write8_device_func whandler, const char *wname, UINT64 unitmask)
{
- memory_private *memdata = machine->memory_data;
- const address_space *space;
-
- /* skip if we can't open the file */
- if (!file)
- return;
-
- /* loop over valid address spaces */
- for (space = memdata->spacelist; space != NULL; space = space->next)
- {
- fprintf(file, "\n\n"
- "====================================================\n"
- "Device '%s' %s address space read handler dump\n"
- "====================================================\n", space->cpu->tag(), space->name);
- dump_map(file, space, &space->read);
-
- fprintf(file, "\n\n"
- "====================================================\n"
- "Device '%s' %s address space write handler dump\n"
- "====================================================\n", space->cpu->tag(), space->name);
- dump_map(file, space, &space->write);
- }
+ UINT32 entry = write().map_range(addrstart, addrend, addrmask, addrmirror);
+ write().handler_write(entry).set_legacy_func(device, whandler, wname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT8 *>(find_backing_memory(addrstart, addrend));
}
-
-
-/***************************************************************************
- INTERNAL INITIALIZATION
-***************************************************************************/
-
-/*-------------------------------------------------
- memory_init_spaces - create the address
- spaces
--------------------------------------------------*/
-
-static void memory_init_spaces(running_machine *machine)
+UINT8 *address_space::install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_device_func rhandler, const char *rname, write8_device_func whandler, const char *wname, UINT64 unitmask)
{
- memory_private *memdata = machine->memory_data;
- address_space **nextptr = (address_space **)&memdata->spacelist;
- int spacenum;
-
- /* create a global watchpoint-filled table */
- memdata->wptable = auto_alloc_array(machine, UINT8, 1 << LEVEL1_BITS);
- memset(memdata->wptable, STATIC_WATCHPOINT, 1 << LEVEL1_BITS);
-
- /* loop over devices */
- device_memory_interface *memory = NULL;
- for (bool gotone = machine->m_devicelist.first(memory); gotone; gotone = memory->next(memory))
- for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
- {
- const address_space_config *spaceconfig = memory->space_config(spacenum);
- if (spaceconfig != NULL)
- {
- address_space *space = auto_alloc_clear(machine, address_space);
- int ashift = spaceconfig->m_addrbus_shift;
- int abits = spaceconfig->m_addrbus_width;
- int dbits = spaceconfig->m_databus_width;
- int logbits = spaceconfig->m_logaddr_width;
- endianness_t endianness = spaceconfig->m_endianness;
- int accessorindex = (dbits == 8) ? 0 : (dbits == 16) ? 1 : (dbits == 32) ? 2 : 3;
- int entrynum;
-
- /* if logbits is 0, revert to abits */
- if (logbits == 0)
- logbits = abits;
-
- /* determine the address and data bits */
- space->machine = machine;
- space->cpu = &memory->device();
- space->name = spaceconfig->m_name;
- space->accessors = memory_accessors[accessorindex][(endianness == ENDIANNESS_LITTLE) ? 0 : 1];
- space->addrmask = 0xffffffffUL >> (32 - abits);
- space->bytemask = (ashift < 0) ? ((space->addrmask << -ashift) | ((1 << -ashift) - 1)) : (space->addrmask >> ashift);
- space->logaddrmask = 0xffffffffUL >> (32 - logbits);
- space->logbytemask = (ashift < 0) ? ((space->logaddrmask << -ashift) | ((1 << -ashift) - 1)) : (space->logaddrmask >> ashift);
- space->spacenum = spacenum;
- space->endianness = endianness;
- space->ashift = ashift;
- space->abits = abits;
- space->dbits = dbits;
- space->addrchars = (abits + 3) / 4;
- space->logaddrchars = (logbits + 3) / 4;
- space->log_unmap = TRUE;
-
- /* allocate subtable information; we malloc this manually because it will be realloc'ed */
- space->read.subtable = auto_alloc_array_clear(machine, subtable_data, SUBTABLE_COUNT);
- space->write.subtable = auto_alloc_array_clear(machine, subtable_data, SUBTABLE_COUNT);
-
- /* allocate the handler table */
- space->read.handlers[0] = auto_alloc_array_clear(machine, handler_data, ARRAY_LENGTH(space->read.handlers));
- space->write.handlers[0] = auto_alloc_array_clear(machine, handler_data, ARRAY_LENGTH(space->write.handlers));
- for (entrynum = 1; entrynum < ARRAY_LENGTH(space->read.handlers); entrynum++)
- {
- space->read.handlers[entrynum] = space->read.handlers[0] + entrynum;
- space->write.handlers[entrynum] = space->write.handlers[0] + entrynum;
- }
-
- /* init the static handlers */
- for (entrynum = 0; entrynum < ENTRY_COUNT; entrynum++)
- {
- space->read.handlers[entrynum]->handler.generic = get_static_handler(space->dbits, 0, entrynum);
- space->read.handlers[entrynum]->object = space;
- space->write.handlers[entrynum]->handler.generic = get_static_handler(space->dbits, 1, entrynum);
- space->write.handlers[entrynum]->object = space;
- }
-
- /* make sure we fix up the mask for the unmap and watchpoint handlers */
- space->read.handlers[STATIC_UNMAP]->bytemask = ~0;
- space->write.handlers[STATIC_UNMAP]->bytemask = ~0;
- space->read.handlers[STATIC_WATCHPOINT]->bytemask = ~0;
- space->write.handlers[STATIC_WATCHPOINT]->bytemask = ~0;
-
- /* allocate memory */
- space->read.machine = machine;
- space->read.table = auto_alloc_array(machine, UINT8, 1 << LEVEL1_BITS);
- space->write.machine = machine;
- space->write.table = auto_alloc_array(machine, UINT8, 1 << LEVEL1_BITS);
-
- /* initialize everything to unmapped */
- memset(space->read.table, STATIC_UNMAP, 1 << LEVEL1_BITS);
- memset(space->write.table, STATIC_UNMAP, 1 << LEVEL1_BITS);
-
- /* initialize the lookups */
- space->readlookup = space->read.table;
- space->writelookup = space->write.table;
-
- /* set the direct access information base */
- space->direct.raw = space->direct.decrypted = NULL;
- space->direct.bytemask = space->bytemask;
- space->direct.bytestart = 1;
- space->direct.byteend = 0;
- space->direct.entry = STATIC_UNMAP;
- space->directupdate = NULL;
-
- /* link us in */
- *nextptr = space;
- nextptr = (address_space **)&space->next;
-
- /* notify the device */
- memory->set_address_space(spacenum, space);
- }
- }
+ install_legacy_handler(device, addrstart, addrend, addrmask, addrmirror, rhandler, rname, unitmask);
+ return install_legacy_handler(device, addrstart, addrend, addrmask, addrmirror, whandler, wname, unitmask);
}
-/*-------------------------------------------------
- memory_init_preflight - verify the memory structs
- and track which banks are referenced
--------------------------------------------------*/
+//-------------------------------------------------
+// install_handler - install 16-bit read/write
+// delegate handlers for the space
+//-------------------------------------------------
-static void memory_init_preflight(running_machine *machine)
+UINT16 *address_space::install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_delegate handler, UINT64 unitmask)
{
- memory_private *memdata = machine->memory_data;
- address_space *space;
-
- /* reset the banking state */
- memdata->banknext = STATIC_BANK1;
-
- /* loop over valid address spaces */
- for (space = (address_space *)memdata->spacelist; space != NULL; space = (address_space *)space->next)
- {
- const region_info *devregion = (space->spacenum == ADDRESS_SPACE_0) ? space->machine->region(space->cpu->tag()) : NULL;
- int devregionsize = (devregion != NULL) ? devregion->bytes() : 0;
- address_map_entry *entry;
- int entrynum;
-
- /* allocate the address map */
- space->map = global_alloc(address_map(space->cpu->baseconfig(), space->spacenum));
-
- /* extract global parameters specified by the map */
- space->unmap = (space->map->m_unmapval == 0) ? 0 : ~0;
- if (space->map->m_globalmask != 0)
- {
- space->addrmask = space->map->m_globalmask;
- space->bytemask = memory_address_to_byte_end(space, space->addrmask);
- }
-
- /* make a pass over the address map, adjusting for the device and getting memory pointers */
- for (entry = space->map->m_entrylist; entry != NULL; entry = entry->m_next)
- {
- /* if we have a share entry, add it to our map */
- if (entry->m_share != NULL)
- memdata->sharemap.add(entry->m_share, UNMAPPED_SHARE_PTR, FALSE);
-
- /* computed adjusted addresses first */
- entry->m_bytestart = entry->m_addrstart;
- entry->m_byteend = entry->m_addrend;
- entry->m_bytemirror = entry->m_addrmirror;
- entry->m_bytemask = entry->m_addrmask;
- adjust_addresses(space, &entry->m_bytestart, &entry->m_byteend, &entry->m_bytemask, &entry->m_bytemirror);
-
- /* if this is a ROM handler without a specified region, attach it to the implicit region */
- if (space->spacenum == ADDRESS_SPACE_0 && entry->m_read.type == AMH_ROM && entry->m_region == NULL)
- {
- /* make sure it fits within the memory region before doing so, however */
- if (entry->m_byteend < devregionsize)
- {
- entry->m_region = space->cpu->tag();
- entry->m_rgnoffs = entry->m_bytestart;
- }
- }
-
- /* validate adjusted addresses against implicit regions */
- if (entry->m_region != NULL && entry->m_share == NULL && entry->m_baseptr == NULL)
- {
- const region_info *region = machine->region(entry->m_region);
- if (region == NULL)
- fatalerror("Error: device '%s' %s space memory map entry %X-%X references non-existant region \"%s\"", space->cpu->tag(), space->name, entry->m_addrstart, entry->m_addrend, entry->m_region);
-
- /* validate the region */
- if (entry->m_rgnoffs + (entry->m_byteend - entry->m_bytestart + 1) > region->bytes())
- fatalerror("Error: device '%s' %s space memory map entry %X-%X extends beyond region \"%s\" size (%X)", space->cpu->tag(), space->name, entry->m_addrstart, entry->m_addrend, entry->m_region, region->bytes());
- }
-
- /* convert any region-relative entries to their memory pointers */
- if (entry->m_region != NULL)
- entry->m_memory = machine->region(entry->m_region)->base() + entry->m_rgnoffs;
- }
-
- /* now loop over all the handlers and enforce the address mask */
- /* we don't loop over map entries because the mask applies to static handlers as well */
- for (entrynum = 0; entrynum < ENTRY_COUNT; entrynum++)
- {
- space->read.handlers[entrynum]->bytemask &= space->bytemask;
- space->write.handlers[entrynum]->bytemask &= space->bytemask;
- }
- }
+ UINT32 entry = read().map_range(addrstart, addrend, addrmask, addrmirror);
+ read().handler_read(entry).set_delegate(handler, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT16 *>(find_backing_memory(addrstart, addrend));
}
-
-/*-------------------------------------------------
- memory_init_populate - populate the memory
- mapping tables with entries
--------------------------------------------------*/
-
-static void memory_init_populate(running_machine *machine)
+UINT16 *address_space::install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write16_delegate handler, UINT64 unitmask)
{
- memory_private *memdata = machine->memory_data;
- address_space *space;
+ UINT32 entry = write().map_range(addrstart, addrend, addrmask, addrmirror);
+ write().handler_write(entry).set_delegate(handler, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT16 *>(find_backing_memory(addrstart, addrend));
+}
- /* loop over valid address spaces */
- for (space = (address_space *)memdata->spacelist; space != NULL; space = (address_space *)space->next)
- if (space->map != NULL)
- {
- const address_map_entry *last_entry = NULL;
+UINT16 *address_space::install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_delegate rhandler, write16_delegate whandler, UINT64 unitmask)
+{
+ install_handler(addrstart, addrend, addrmask, addrmirror, rhandler, unitmask);
+ return install_handler(addrstart, addrend, addrmask, addrmirror, whandler, unitmask);
+}
- /* install the handlers, using the original, unadjusted memory map */
- while (last_entry != space->map->m_entrylist)
- {
- const address_map_entry *entry;
- /* find the entry before the last one we processed */
- for (entry = space->map->m_entrylist; entry->m_next != last_entry; entry = entry->m_next) ;
- last_entry = entry;
+//-------------------------------------------------
+// install_legacy_handler - install 16-bit read/
+// write legacy address space handlers for the
+// space
+//-------------------------------------------------
- /* map both read and write halves */
- memory_init_map_entry(space, entry, ROW_READ);
- memory_init_map_entry(space, entry, ROW_WRITE);
- }
- }
+UINT16 *address_space::install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_space_func rhandler, const char *rname, UINT64 unitmask)
+{
+ UINT32 entry = read().map_range(addrstart, addrend, addrmask, addrmirror);
+ read().handler_read(entry).set_legacy_func(*this, rhandler, rname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT16 *>(find_backing_memory(addrstart, addrend));
}
+UINT16 *address_space::install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write16_space_func whandler, const char *wname, UINT64 unitmask)
+{
+ UINT32 entry = write().map_range(addrstart, addrend, addrmask, addrmirror);
+ write().handler_write(entry).set_legacy_func(*this, whandler, wname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT16 *>(find_backing_memory(addrstart, addrend));
+}
-/*-------------------------------------------------
- memory_init_map_entry - map a single read or
- write entry based on information from an
- address map entry
--------------------------------------------------*/
-
-static void memory_init_map_entry(address_space *space, const address_map_entry *entry, read_or_write readorwrite)
+UINT16 *address_space::install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_space_func rhandler, const char *rname, write16_space_func whandler, const char *wname, UINT64 unitmask)
{
- const map_handler_data *handler = (readorwrite == ROW_READ) ? &entry->m_read : &entry->m_write;
- device_t *device;
+ install_legacy_handler(addrstart, addrend, addrmask, addrmirror, rhandler, rname, unitmask);
+ return install_legacy_handler(addrstart, addrend, addrmask, addrmirror, whandler, wname, unitmask);
+}
- /* based on the handler type, alter the bits, name, funcptr, and object */
- switch (handler->type)
- {
- case AMH_NONE:
- return;
- case AMH_ROM:
- if (readorwrite == ROW_WRITE)
- return;
- /* fall through to the RAM case otherwise */
+//-------------------------------------------------
+// install_legacy_handler - install 16-bit read/
+// write legacy device handlers for the space
+//-------------------------------------------------
- case AMH_RAM:
- _memory_install_ram(space, entry->m_addrstart, entry->m_addrend, entry->m_addrmask, entry->m_addrmirror,
- readorwrite == ROW_READ, readorwrite == ROW_WRITE, NULL);
- break;
+UINT16 *address_space::install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_device_func rhandler, const char *rname, UINT64 unitmask)
+{
+ UINT32 entry = read().map_range(addrstart, addrend, addrmask, addrmirror);
+ read().handler_read(entry).set_legacy_func(device, rhandler, rname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT16 *>(find_backing_memory(addrstart, addrend));
+}
- case AMH_NOP:
- _memory_unmap(space, entry->m_addrstart, entry->m_addrend, entry->m_addrmask, entry->m_addrmirror,
- readorwrite == ROW_READ, readorwrite == ROW_WRITE, TRUE);
- break;
+UINT16 *address_space::install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write16_device_func whandler, const char *wname, UINT64 unitmask)
+{
+ UINT32 entry = write().map_range(addrstart, addrend, addrmask, addrmirror);
+ write().handler_write(entry).set_legacy_func(device, whandler, wname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT16 *>(find_backing_memory(addrstart, addrend));
+}
- case AMH_UNMAP:
- _memory_unmap(space, entry->m_addrstart, entry->m_addrend, entry->m_addrmask, entry->m_addrmirror,
- readorwrite == ROW_READ, readorwrite == ROW_WRITE, FALSE);
- break;
+UINT16 *address_space::install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_device_func rhandler, const char *rname, write16_device_func whandler, const char *wname, UINT64 unitmask)
+{
+ install_legacy_handler(device, addrstart, addrend, addrmask, addrmirror, rhandler, rname, unitmask);
+ return install_legacy_handler(device, addrstart, addrend, addrmask, addrmirror, whandler, wname, unitmask);
+}
- case AMH_HANDLER:
- switch ((handler->bits != 0) ? handler->bits : space->dbits)
- {
- case 8:
- _memory_install_handler8(space, entry->m_addrstart, entry->m_addrend, entry->m_addrmask, entry->m_addrmirror,
- (readorwrite == ROW_READ) ? handler->handler.read.shandler8 : NULL, handler->name,
- (readorwrite == ROW_WRITE) ? handler->handler.write.shandler8 : NULL, handler->name,
- handler->mask);
- break;
- case 16:
- _memory_install_handler16(space, entry->m_addrstart, entry->m_addrend, entry->m_addrmask, entry->m_addrmirror,
- (readorwrite == ROW_READ) ? handler->handler.read.shandler16 : NULL, handler->name,
- (readorwrite == ROW_WRITE) ? handler->handler.write.shandler16 : NULL, handler->name,
- handler->mask);
- break;
+//-------------------------------------------------
+// install_handler - install 32-bit read/write
+// delegate handlers for the space
+//-------------------------------------------------
- case 32:
- _memory_install_handler32(space, entry->m_addrstart, entry->m_addrend, entry->m_addrmask, entry->m_addrmirror,
- (readorwrite == ROW_READ) ? handler->handler.read.shandler32 : NULL, handler->name,
- (readorwrite == ROW_WRITE) ? handler->handler.write.shandler32 : NULL, handler->name,
- handler->mask);
- break;
+UINT32 *address_space::install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_delegate handler, UINT64 unitmask)
+{
+ UINT32 entry = read().map_range(addrstart, addrend, addrmask, addrmirror);
+ read().handler_read(entry).set_delegate(handler, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT32 *>(find_backing_memory(addrstart, addrend));
+}
- case 64:
- _memory_install_handler64(space, entry->m_addrstart, entry->m_addrend, entry->m_addrmask, entry->m_addrmirror,
- (readorwrite == ROW_READ) ? handler->handler.read.shandler64 : NULL, handler->name,
- (readorwrite == ROW_WRITE) ? handler->handler.write.shandler64 : NULL, handler->name,
- handler->mask);
- break;
- }
- break;
+UINT32 *address_space::install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write32_delegate handler, UINT64 unitmask)
+{
+ UINT32 entry = write().map_range(addrstart, addrend, addrmask, addrmirror);
+ write().handler_write(entry).set_delegate(handler, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT32 *>(find_backing_memory(addrstart, addrend));
+}
- case AMH_DEVICE_HANDLER:
- device = space->machine->device(handler->tag);
- if (device == NULL)
- fatalerror("Attempted to map a non-existent device '%s' in space %s of device '%s'\n", handler->tag, space->name, (space->cpu != NULL) ? space->cpu->tag() : "??");
- switch ((handler->bits != 0) ? handler->bits : space->dbits)
- {
- case 8:
- _memory_install_device_handler8(space, device, entry->m_addrstart, entry->m_addrend, entry->m_addrmask, entry->m_addrmirror,
- (readorwrite == ROW_READ) ? handler->handler.read.dhandler8 : NULL, handler->name,
- (readorwrite == ROW_WRITE) ? handler->handler.write.dhandler8 : NULL, handler->name,
- handler->mask);
- break;
+UINT32 *address_space::install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_delegate rhandler, write32_delegate whandler, UINT64 unitmask)
+{
+ install_handler(addrstart, addrend, addrmask, addrmirror, rhandler, unitmask);
+ return install_handler(addrstart, addrend, addrmask, addrmirror, whandler, unitmask);
+}
- case 16:
- _memory_install_device_handler16(space, device, entry->m_addrstart, entry->m_addrend, entry->m_addrmask, entry->m_addrmirror,
- (readorwrite == ROW_READ) ? handler->handler.read.dhandler16 : NULL, handler->name,
- (readorwrite == ROW_WRITE) ? handler->handler.write.dhandler16 : NULL, handler->name,
- handler->mask);
- break;
- case 32:
- _memory_install_device_handler32(space, device, entry->m_addrstart, entry->m_addrend, entry->m_addrmask, entry->m_addrmirror,
- (readorwrite == ROW_READ) ? handler->handler.read.dhandler32 : NULL, handler->name,
- (readorwrite == ROW_WRITE) ? handler->handler.write.dhandler32 : NULL, handler->name,
- handler->mask);
- break;
+//-------------------------------------------------
+// install_legacy_handler - install 32-bit read/
+// write legacy address space handlers for the
+// space
+//-------------------------------------------------
- case 64:
- _memory_install_device_handler64(space, device, entry->m_addrstart, entry->m_addrend, entry->m_addrmask, entry->m_addrmirror,
- (readorwrite == ROW_READ) ? handler->handler.read.dhandler64 : NULL, handler->name,
- (readorwrite == ROW_WRITE) ? handler->handler.write.dhandler64 : NULL, handler->name,
- handler->mask);
- break;
- }
- break;
+UINT32 *address_space::install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_space_func rhandler, const char *rname, UINT64 unitmask)
+{
+ UINT32 entry = read().map_range(addrstart, addrend, addrmask, addrmirror);
+ read().handler_read(entry).set_legacy_func(*this, rhandler, rname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT32 *>(find_backing_memory(addrstart, addrend));
+}
- case AMH_PORT:
- _memory_install_port(space, entry->m_addrstart, entry->m_addrend, entry->m_addrmask, entry->m_addrmirror,
- (readorwrite == ROW_READ) ? handler->tag : NULL,
- (readorwrite == ROW_WRITE) ? handler->tag : NULL);
- break;
+UINT32 *address_space::install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write32_space_func whandler, const char *wname, UINT64 unitmask)
+{
+ UINT32 entry = write().map_range(addrstart, addrend, addrmask, addrmirror);
+ write().handler_write(entry).set_legacy_func(*this, whandler, wname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT32 *>(find_backing_memory(addrstart, addrend));
+}
- case AMH_BANK:
- _memory_install_bank(space, entry->m_addrstart, entry->m_addrend, entry->m_addrmask, entry->m_addrmirror,
- (readorwrite == ROW_READ) ? handler->tag : NULL,
- (readorwrite == ROW_WRITE) ? handler->tag : NULL);
- break;
- }
+UINT32 *address_space::install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_space_func rhandler, const char *rname, write32_space_func whandler, const char *wname, UINT64 unitmask)
+{
+ install_legacy_handler(addrstart, addrend, addrmask, addrmirror, rhandler, rname, unitmask);
+ return install_legacy_handler(addrstart, addrend, addrmask, addrmirror, whandler, wname, unitmask);
}
-/*-------------------------------------------------
- memory_init_allocate - allocate memory for
- device address spaces
--------------------------------------------------*/
+//-------------------------------------------------
+// install_legacy_handler - install 32-bit read/
+// write legacy device handlers for the space
+//-------------------------------------------------
-static void memory_init_allocate(running_machine *machine)
+UINT32 *address_space::install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_device_func rhandler, const char *rname, UINT64 unitmask)
{
- memory_private *memdata = machine->memory_data;
- address_space *space;
-
- /* loop over valid address spaces */
- for (space = (address_space *)memdata->spacelist; space != NULL; space = (address_space *)space->next)
- {
- address_map_entry *unassigned = NULL;
- address_map_entry *entry;
- memory_block *prev_memblock_head = memdata->memory_block_list;
- memory_block *memblock;
-
- /* make a first pass over the memory map and track blocks with hardcoded pointers */
- /* we do this to make sure they are found by space_find_backing_memory first */
- for (entry = space->map->m_entrylist; entry != NULL; entry = entry->m_next)
- if (entry->m_memory != NULL)
- block_allocate(space, entry->m_bytestart, entry->m_byteend, entry->m_memory);
-
- /* loop over all blocks just allocated and assign pointers from them */
- for (memblock = memdata->memory_block_list; memblock != prev_memblock_head; memblock = memblock->next)
- unassigned = block_assign_intersecting(space, memblock->bytestart, memblock->byteend, memblock->data);
-
- /* if we don't have an unassigned pointer yet, try to find one */
- if (unassigned == NULL)
- unassigned = block_assign_intersecting(space, ~0, 0, NULL);
-
- /* loop until we've assigned all memory in this space */
- while (unassigned != NULL)
- {
- offs_t curbytestart, curbyteend;
- int changed;
- void *block;
+ UINT32 entry = read().map_range(addrstart, addrend, addrmask, addrmirror);
+ read().handler_read(entry).set_legacy_func(device, rhandler, rname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT32 *>(find_backing_memory(addrstart, addrend));
+}
- /* work in MEMORY_BLOCK_CHUNK-sized chunks */
- offs_t curblockstart = unassigned->m_bytestart / MEMORY_BLOCK_CHUNK;
- offs_t curblockend = unassigned->m_byteend / MEMORY_BLOCK_CHUNK;
+UINT32 *address_space::install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write32_device_func whandler, const char *wname, UINT64 unitmask)
+{
+ UINT32 entry = write().map_range(addrstart, addrend, addrmask, addrmirror);
+ write().handler_write(entry).set_legacy_func(device, whandler, wname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT32 *>(find_backing_memory(addrstart, addrend));
+}
- /* loop while we keep finding unassigned blocks in neighboring MEMORY_BLOCK_CHUNK chunks */
- do
- {
- changed = FALSE;
+UINT32 *address_space::install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_device_func rhandler, const char *rname, write32_device_func whandler, const char *wname, UINT64 unitmask)
+{
+ install_legacy_handler(device, addrstart, addrend, addrmask, addrmirror, rhandler, rname, unitmask);
+ return install_legacy_handler(device, addrstart, addrend, addrmask, addrmirror, whandler, wname, unitmask);
+}
- /* scan for unmapped blocks in the adjusted map */
- for (entry = space->map->m_entrylist; entry != NULL; entry = entry->m_next)
- if (entry->m_memory == NULL && entry != unassigned && space_needs_backing_store(space, entry))
- {
- offs_t blockstart, blockend;
- /* get block start/end blocks for this block */
- blockstart = entry->m_bytestart / MEMORY_BLOCK_CHUNK;
- blockend = entry->m_byteend / MEMORY_BLOCK_CHUNK;
+//-------------------------------------------------
+// install_handler64 - install 64-bit read/write
+// delegate handlers for the space
+//-------------------------------------------------
- /* if we intersect or are adjacent, adjust the start/end */
- if (blockstart <= curblockend + 1 && blockend >= curblockstart - 1)
- {
- if (blockstart < curblockstart)
- curblockstart = blockstart, changed = TRUE;
- if (blockend > curblockend)
- curblockend = blockend, changed = TRUE;
- }
- }
- } while (changed);
+UINT64 *address_space::install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_delegate handler, UINT64 unitmask)
+{
+ UINT32 entry = read().map_range(addrstart, addrend, addrmask, addrmirror);
+ read().handler_read(entry).set_delegate(handler, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT64 *>(find_backing_memory(addrstart, addrend));
+}
- /* we now have a block to allocate; do it */
- curbytestart = curblockstart * MEMORY_BLOCK_CHUNK;
- curbyteend = curblockend * MEMORY_BLOCK_CHUNK + (MEMORY_BLOCK_CHUNK - 1);
- block = block_allocate(space, curbytestart, curbyteend, NULL);
+UINT64 *address_space::install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write64_delegate handler, UINT64 unitmask)
+{
+ UINT32 entry = write().map_range(addrstart, addrend, addrmask, addrmirror);
+ write().handler_write(entry).set_delegate(handler, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT64 *>(find_backing_memory(addrstart, addrend));
+}
- /* assign memory that intersected the new block */
- unassigned = block_assign_intersecting(space, curbytestart, curbyteend, (UINT8 *)block);
- }
- }
+UINT64 *address_space::install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_delegate rhandler, write64_delegate whandler, UINT64 unitmask)
+{
+ install_handler(addrstart, addrend, addrmask, addrmirror, rhandler, unitmask);
+ return install_handler(addrstart, addrend, addrmask, addrmirror, whandler, unitmask);
}
-/*-------------------------------------------------
- memory_init_locate - find all the requested
- pointers into the final allocated memory
--------------------------------------------------*/
+//-------------------------------------------------
+// install_legacy_handler - install 64-bit read/
+// write legacy address space handlers for the
+// space
+//-------------------------------------------------
-static void memory_init_locate(running_machine *machine)
+UINT64 *address_space::install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_space_func rhandler, const char *rname, UINT64 unitmask)
{
- memory_private *memdata = machine->memory_data;
- address_space *space;
- bank_info *bank;
+ UINT32 entry = read().map_range(addrstart, addrend, addrmask, addrmirror);
+ read().handler_read(entry).set_legacy_func(*this, rhandler, rname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT64 *>(find_backing_memory(addrstart, addrend));
+}
- /* loop over valid address spaces */
- for (space = (address_space *)memdata->spacelist; space != NULL; space = (address_space *)space->next)
- {
- const address_map_entry *entry;
+UINT64 *address_space::install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write64_space_func whandler, const char *wname, UINT64 unitmask)
+{
+ UINT32 entry = write().map_range(addrstart, addrend, addrmask, addrmirror);
+ write().handler_write(entry).set_legacy_func(*this, whandler, wname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT64 *>(find_backing_memory(addrstart, addrend));
+}
- /* fill in base/size entries */
- for (entry = space->map->m_entrylist; entry != NULL; entry = entry->m_next)
- {
- if (entry->m_baseptr != NULL)
- *entry->m_baseptr = entry->m_memory;
- if (entry->m_baseptroffs_plus1 != 0)
- *(void **)(reinterpret_cast<UINT8 *>(machine->driver_data<void>()) + entry->m_baseptroffs_plus1 - 1) = entry->m_memory;
- if (entry->m_genbaseptroffs_plus1 != 0)
- *(void **)((UINT8 *)&machine->generic + entry->m_genbaseptroffs_plus1 - 1) = entry->m_memory;
- if (entry->m_sizeptr != NULL)
- *entry->m_sizeptr = entry->m_byteend - entry->m_bytestart + 1;
- if (entry->m_sizeptroffs_plus1 != 0)
- *(size_t *)(reinterpret_cast<UINT8 *>(machine->driver_data<void>()) + entry->m_sizeptroffs_plus1 - 1) = entry->m_byteend - entry->m_bytestart + 1;
- if (entry->m_gensizeptroffs_plus1 != 0)
- *(size_t *)((UINT8 *)&machine->generic + entry->m_gensizeptroffs_plus1 - 1) = entry->m_byteend - entry->m_bytestart + 1;
- }
- }
+UINT64 *address_space::install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_space_func rhandler, const char *rname, write64_space_func whandler, const char *wname, UINT64 unitmask)
+{
+ install_legacy_handler(addrstart, addrend, addrmask, addrmirror, rhandler, rname, unitmask);
+ return install_legacy_handler(addrstart, addrend, addrmask, addrmirror, whandler, wname, unitmask);
+}
- /* once this is done, find the starting bases for the banks */
- for (bank = memdata->banklist; bank != NULL; bank = bank->next)
- {
- address_map_entry *entry;
- bank_reference *ref;
- int foundit = FALSE;
-
- /* set the initial bank pointer */
- for (ref = bank->reflist; !foundit && ref != NULL; ref = ref->next)
- for (entry = ref->space->map->m_entrylist; entry != NULL; entry = entry->m_next)
- if (entry->m_bytestart == bank->bytestart && entry->m_memory != NULL)
- {
- memdata->bank_ptr[bank->index] = (UINT8 *)entry->m_memory;
- foundit = TRUE;
- VPRINTF(("assigned bank '%s' pointer to memory from range %08X-%08X [%p]\n", bank->tag, entry->m_addrstart, entry->m_addrend, entry->m_memory));
- break;
- }
- /* if the entry was set ahead of time, override the automatically found pointer */
- if (bank->tag[0] != '~' && bank->curentry != MAX_BANK_ENTRIES)
- memdata->bank_ptr[bank->index] = (UINT8 *)bank->entry[bank->curentry];
- }
+//-------------------------------------------------
+// install_legacy_handler - install 64-bit read/
+// write legacy device handlers for the space
+//-------------------------------------------------
- /* request a callback to fix up the banks when done */
- state_save_register_postload(machine, bank_reattach, NULL);
+UINT64 *address_space::install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_device_func rhandler, const char *rname, UINT64 unitmask)
+{
+ UINT32 entry = read().map_range(addrstart, addrend, addrmask, addrmirror);
+ read().handler_read(entry).set_legacy_func(device, rhandler, rname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT64 *>(find_backing_memory(addrstart, addrend));
}
-
-/*-------------------------------------------------
- memory_exit - free memory
--------------------------------------------------*/
-
-static void memory_exit(running_machine &machine)
+UINT64 *address_space::install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write64_device_func whandler, const char *wname, UINT64 unitmask)
{
- memory_private *memdata = machine.memory_data;
- address_space *space;
+ UINT32 entry = write().map_range(addrstart, addrend, addrmask, addrmirror);
+ write().handler_write(entry).set_legacy_func(device, whandler, wname, unitmask);
+ generate_memdump(machine);
+ return reinterpret_cast<UINT64 *>(find_backing_memory(addrstart, addrend));
+}
- /* free all the address spaces and tables */
- for (space = (address_space *)memdata->spacelist; space != NULL; space = space->next)
- {
- /* free the address map and tables */
- global_free(space->map);
- }
+UINT64 *address_space::install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_device_func rhandler, const char *rname, write64_device_func whandler, const char *wname, UINT64 unitmask)
+{
+ install_legacy_handler(device, addrstart, addrend, addrmask, addrmirror, rhandler, rname, unitmask);
+ return install_legacy_handler(device, addrstart, addrend, addrmask, addrmirror, whandler, wname, unitmask);
}
-/***************************************************************************
- MEMORY MAPPING HELPERS
-***************************************************************************/
+//**************************************************************************
+// INTERNAL INITIALIZATION
+//**************************************************************************
-/*-------------------------------------------------
- space_map_range - maps a range of addresses
- to the specified handler within an address
- space
--------------------------------------------------*/
-
-static void space_map_range(address_space *space, read_or_write readorwrite, int handlerbits, int handlerunitmask, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, genf *handler, void *object, const char *handler_name)
-{
- address_table *tabledata = (readorwrite == ROW_WRITE) ? &space->write : &space->read;
- int reset_write = (space->writelookup == space->write.table);
- int reset_read = (space->readlookup == space->read.table);
- offs_t bytestart, byteend, bytemask, bytemirror;
- UINT8 entry;
-
- /* sanity checks */
- assert(space != NULL);
- assert(handlerbits == 8 || handlerbits == 16 || handlerbits == 32 || handlerbits == 64);
-
- /* adjust the incoming addresses */
- bytestart = addrstart;
- byteend = addrend;
- bytemirror = addrmirror;
- bytemask = addrmask;
- adjust_addresses(space, &bytestart, &byteend, &bytemask, &bytemirror);
-
- /* validity checks */
- assert_always(!HANDLER_IS_ROM(handler), "space_map_range called with ROM after initialization");
- assert_always(!HANDLER_IS_RAM(handler), "space_map_range called with RAM after initialization");
- assert_always(addrstart <= addrend, "space_map_range called with start greater than end");
- assert_always(handlerbits <= space->dbits, "space_map_range called with handlers larger than the address space");
- assert_always((bytestart & (space->dbits / 8 - 1)) == 0, "space_map_range called with misaligned start address");
- assert_always((byteend & (space->dbits / 8 - 1)) == (space->dbits / 8 - 1), "space_map_range called with misaligned end address");
-
- /* get the final handler index */
- entry = table_assign_handler(space, tabledata->handlers, object, handler, handler_name, bytestart, byteend, bytemask);
-
- /* fix up the handler if a stub is required */
- if (handlerbits != space->dbits)
- table_compute_subhandler(tabledata->handlers, entry, readorwrite, space->dbits, space->endianness, handlerbits, handlerunitmask);
-
- /* populate it */
- table_populate_range_mirrored(space, tabledata, bytestart, byteend, bytemirror, entry);
-
- /* reset read/write pointers if necessary (could have moved due to realloc) */
- if (reset_write)
- space->writelookup = space->write.table;
- if (reset_read)
- space->readlookup = space->read.table;
-
- /* recompute any direct access on this space if it is a read modification */
- if (readorwrite == ROW_READ && entry == space->direct.entry)
- {
- space->direct.entry = STATIC_UNMAP;
- space->direct.bytestart = 1;
- space->direct.byteend = 0;
- }
-}
+//**************************************************************************
+// MEMORY MAPPING HELPERS
+//**************************************************************************
-/*-------------------------------------------------
- space_find_backing_memory - return a pointer to
- the base of RAM associated with the given
- device and offset
--------------------------------------------------*/
+//-------------------------------------------------
+// find_backing_memory - return a pointer to
+// the base of RAM associated with the given
+// device and offset
+//-------------------------------------------------
-static void *space_find_backing_memory(const address_space *space, offs_t addrstart, offs_t addrend)
+void *address_space::find_backing_memory(offs_t addrstart, offs_t addrend)
{
- offs_t bytestart = memory_address_to_byte(space, addrstart);
- offs_t byteend = memory_address_to_byte_end(space, addrend);
- memory_private *memdata = space->machine->memory_data;
- address_map_entry *entry;
- memory_block *block;
+ offs_t bytestart = address_to_byte(addrstart);
+ offs_t byteend = address_to_byte_end(addrend);
- VPRINTF(("space_find_backing_memory('%s',%s,%08X-%08X) -> ", space->cpu->tag(), space->name, bytestart, byteend));
+ VPRINTF(("address_space::find_backing_memory('%s',%s,%08X-%08X) -> ", m_device.tag(), m_name, bytestart, byteend));
- /* look in the address map first */
- for (entry = space->map->m_entrylist; entry != NULL; entry = entry->m_next)
+ // look in the address map first
+ for (address_map_entry *entry = m_map->m_entrylist.first(); entry != NULL; entry = entry->next())
{
offs_t maskstart = bytestart & entry->m_bytemask;
offs_t maskend = byteend & entry->m_bytemask;
@@ -2222,12 +2545,12 @@ static void *space_find_backing_memory(const address_space *space, offs_t addrst
}
}
- /* if not found there, look in the allocated blocks */
- for (block = memdata->memory_block_list; block != NULL; block = block->next)
- if (block->space == space && block->bytestart <= bytestart && block->byteend >= byteend)
+ // if not found there, look in the allocated blocks
+ for (memory_block *block = m_machine.memory_data->blocklist.first(); block != NULL; block = block->next())
+ if (block->contains(*this, bytestart, byteend))
{
- VPRINTF(("found in allocated memory block %08X-%08X [%p]\n", block->bytestart, block->byteend, block->data + (bytestart - block->bytestart)));
- return block->data + bytestart - block->bytestart;
+ VPRINTF(("found in allocated memory block %08X-%08X [%p]\n", block->bytestart(), block->byteend(), block->data() + (bytestart - block->bytestart())));
+ return block->data() + bytestart - block->bytestart();
}
VPRINTF(("did not find\n"));
@@ -2235,619 +2558,582 @@ static void *space_find_backing_memory(const address_space *space, offs_t addrst
}
-/*-------------------------------------------------
- space_needs_backing_store - return whether a
- given memory map entry implies the need of
- allocating and registering memory
--------------------------------------------------*/
+//-------------------------------------------------
+// space_needs_backing_store - return whether a
+// given memory map entry implies the need of
+// allocating and registering memory
+//-------------------------------------------------
-static int space_needs_backing_store(const address_space *space, const address_map_entry *entry)
+bool address_space::needs_backing_store(const address_map_entry *entry)
{
- /* if we are asked to provide a base pointer, then yes, we do need backing */
+ // if we are asked to provide a base pointer, then yes, we do need backing
if (entry->m_baseptr != NULL || entry->m_baseptroffs_plus1 != 0 || entry->m_genbaseptroffs_plus1 != 0)
- return TRUE;
+ return true;
- /* if we're writing to any sort of bank or RAM, then yes, we do need backing */
- if (entry->m_write.type == AMH_BANK || entry->m_write.type == AMH_RAM)
- return TRUE;
+ // if we're writing to any sort of bank or RAM, then yes, we do need backing
+ if (entry->m_write.m_type == AMH_BANK || entry->m_write.m_type == AMH_RAM)
+ return true;
- /* if we're reading from RAM or from ROM outside of address space 0 or its region, then yes, we do need backing */
- const region_info *region = space->machine->region(space->cpu->tag());
- if (entry->m_read.type == AMH_RAM ||
- (entry->m_read.type == AMH_ROM && (space->spacenum != ADDRESS_SPACE_0 || region == NULL || entry->m_addrstart >= region->bytes())))
- return TRUE;
+ // if we're reading from RAM or from ROM outside of address space 0 or its region, then yes, we do need backing
+ const region_info *region = m_machine.region(m_device.tag());
+ if (entry->m_read.m_type == AMH_RAM ||
+ (entry->m_read.m_type == AMH_ROM && (m_spacenum != ADDRESS_SPACE_0 || region == NULL || entry->m_addrstart >= region->bytes())))
+ return true;
- /* all other cases don't need backing */
- return FALSE;
+ // all other cases don't need backing
+ return false;
}
-/***************************************************************************
- BANKING HELPERS
-***************************************************************************/
+//**************************************************************************
+// BANKING HELPERS
+//**************************************************************************
-/*-------------------------------------------------
- bank_find_or_allocate - allocate a new
- bank, or find an existing one, and return the
- read/write handler
--------------------------------------------------*/
+//-------------------------------------------------
+// bank_find_or_allocate - allocate a new
+// bank, or find an existing one, and return the
+// read/write handler
+//-------------------------------------------------
-static genf *bank_find_or_allocate(const address_space *space, const char *tag, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read_or_write readorwrite)
+memory_bank &address_space::bank_find_or_allocate(const char *tag, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read_or_write readorwrite)
{
- memory_private *memdata = space->machine->memory_data;
+ memory_private *memdata = m_machine.memory_data;
+
+ // adjust the addresses, handling mirrors and such
offs_t bytemirror = addrmirror;
offs_t bytestart = addrstart;
offs_t bytemask = addrmask;
offs_t byteend = addrend;
- bank_info *bank = NULL;
- char temptag[10];
- char name[30];
-
- /* adjust the addresses, handling mirrors and such */
- adjust_addresses(space, &bytestart, &byteend, &bytemask, &bytemirror);
+ adjust_addresses(bytestart, byteend, bytemask, bytemirror);
- /* if this bank is named, look it up */
+ // if this bank is named, look it up
+ memory_bank *bank = NULL;
if (tag != NULL)
bank = memdata->bankmap.find_hash_only(tag);
- /* else try to find an exact match */
+ // else try to find an exact match
else
- {
- for (bank = memdata->banklist; bank != NULL; bank = bank->next)
- if (bank->tag[0] == '~' && bank->bytestart == bytestart && bank->byteend == byteend && bank->reflist != NULL && bank->reflist->space == space)
+ for (bank = memdata->banklist.first(); bank != NULL; bank = bank->next())
+ if (bank->anonymous() && bank->references_space(*this, ROW_READWRITE) && bank->matches_exactly(bytestart, byteend))
break;
- }
- /* if we don't have a bank yet, find a free one */
+ // if we don't have a bank yet, find a free one
if (bank == NULL)
{
+ // handle failure
int banknum = memdata->banknext++;
-
- /* handle failure */
if (banknum > STATIC_BANKMAX)
{
if (tag != NULL)
- fatalerror("Unable to allocate new bank '%s'", tag);
+ throw emu_fatalerror("Unable to allocate new bank '%s'", tag);
else
- fatalerror("Unable to allocate bank for RAM/ROM area %X-%X\n", bytestart, byteend);
+ throw emu_fatalerror("Unable to allocate bank for RAM/ROM area %X-%X\n", bytestart, byteend);
}
- /* generate an internal tag if we don't have one */
- if (tag == NULL)
- {
- sprintf(temptag, "~%d~", banknum);
- tag = temptag;
- sprintf(name, "Internal bank #%d", banknum);
- }
- else
- sprintf(name, "Bank '%s'", tag);
-
- /* allocate the bank */
- bank = (bank_info *)auto_alloc_array_clear(space->machine, UINT8, sizeof(bank_info) + strlen(tag) + 1 + strlen(name));
-
- /* populate it */
- bank->index = banknum;
- bank->handler = (void *)(FPTR)(STATIC_BANK1 + banknum - 1);
- bank->bytestart = bytestart;
- bank->byteend = byteend;
- bank->curentry = MAX_BANK_ENTRIES;
- strcpy(bank->tag, tag);
- bank->name = bank->tag + strlen(tag) + 1;
- strcpy(bank->name, name);
-
- /* add us to the list */
- bank->next = memdata->banklist;
- memdata->banklist = bank;
-
- /* for named banks, add to the map and register for save states */
- if (tag[0] != '~')
- {
- memdata->bankmap.add_unique_hash(tag, bank, FALSE);
- if (state_save_registration_allowed(space->machine))
- state_save_register_item(space->machine, "memory", bank->tag, 0, bank->curentry);
- }
- }
+ // allocate the bank
+ bank = auto_alloc(&m_machine, memory_bank(*this, banknum, bytestart, byteend, tag));
+ memdata->banklist.append(*bank);
- /* update the read/write state for this bank */
- if (readorwrite == ROW_READ)
- bank->read = TRUE;
- if (readorwrite == ROW_WRITE)
- bank->write = TRUE;
+ // for named banks, add to the map and register for save states
+ if (tag != NULL)
+ memdata->bankmap.add_unique_hash(tag, bank, false);
+ }
- /* add a reference for this space */
- add_bank_reference(bank, space);
- return (genf *)bank->handler;
+ // add a reference for this space
+ bank->add_reference(*this, readorwrite);
+ return *bank;
}
-/*-------------------------------------------------
- bank_reattach - reconnect banks after a load
--------------------------------------------------*/
-static STATE_POSTLOAD( bank_reattach )
+//**************************************************************************
+// TABLE MANAGEMENT
+//**************************************************************************
+
+//-------------------------------------------------
+// address_table - constructor
+//-------------------------------------------------
+
+address_table::address_table(address_space &space, bool large)
+ : m_table(auto_alloc_array(&space.m_machine, UINT8, 1 << LEVEL1_BITS)),
+ m_live_lookup(m_table),
+ m_space(space),
+ m_large(large),
+ m_subtable(auto_alloc_array(&space.m_machine, subtable_data, SUBTABLE_COUNT)),
+ m_subtable_alloc(0)
{
- memory_private *memdata = machine->memory_data;
- bank_info *bank;
+ // make our static table all watchpoints
+ if (s_watchpoint_table[0] != STATIC_WATCHPOINT)
+ memset(s_watchpoint_table, STATIC_WATCHPOINT, sizeof(s_watchpoint_table));
- /* once this is done, find the starting bases for the banks */
- for (bank = memdata->banklist; bank != NULL; bank = bank->next)
- if (bank->tag[0] != '~')
- {
- /* if this entry has a changed entry, set the appropriate pointer */
- if (bank->curentry != MAX_BANK_ENTRIES)
- memdata->bank_ptr[bank->index] = (UINT8 *)bank->entry[bank->curentry];
- }
+ // initialize everything to unmapped
+ memset(m_table, STATIC_UNMAP, 1 << LEVEL1_BITS);
}
+//-------------------------------------------------
+// ~address_table - destructor
+//-------------------------------------------------
-/***************************************************************************
- TABLE MANAGEMENT
-***************************************************************************/
+address_table::~address_table()
+{
+ auto_free(&m_space.m_machine, m_table);
+ auto_free(&m_space.m_machine, m_subtable);
+}
-/*-------------------------------------------------
- table_assign_handler - finds the index of a
- handler, or allocates a new one as necessary
--------------------------------------------------*/
-static UINT8 table_assign_handler(const address_space *space, handler_data **table, void *object, genf *handler, const char *handler_name, offs_t bytestart, offs_t byteend, offs_t bytemask)
-{
- int entry;
+//-------------------------------------------------
+// map_range - finds an approprite handler entry
+// and requests to populate the address map with
+// it
+//-------------------------------------------------
- /* all static handlers are hardcoded */
- if (HANDLER_IS_STATIC(handler))
- {
- entry = (FPTR)handler;
+UINT8 address_table::map_range(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, UINT8 staticentry)
+{
+ // convert addresses to bytes
+ offs_t bytestart = addrstart;
+ offs_t byteend = addrend;
+ offs_t bytemask = addrmask;
+ offs_t bytemirror = addrmirror;
+ m_space.adjust_addresses(bytestart, byteend, bytemask, bytemirror);
- /* if it is a bank, copy in the relevant information */
- if (HANDLER_IS_BANK(handler))
- {
- handler_data *hdata = table[entry];
- hdata->bytestart = bytestart;
- hdata->byteend = byteend;
- hdata->bytemask = bytemask;
- hdata->bankbaseptr = &space->machine->memory_data->bank_ptr[entry];
- hdata->name = handler_name;
- }
- return entry;
- }
+ // validity checks
+ assert_always(addrstart <= addrend, "address_table::map_range called with start greater than end");
+ assert_always((bytestart & (m_space.data_width() / 8 - 1)) == 0, "address_table::map_range called with misaligned start address");
+ assert_always((byteend & (m_space.data_width() / 8 - 1)) == (m_space.data_width() / 8 - 1), "address_table::map_range called with misaligned end address");
- /* otherwise, we have to search */
- for (entry = STATIC_COUNT; entry < SUBTABLE_BASE; entry++)
+ // if we weren't given an explicit entry, find a free one
+ UINT8 entry = staticentry;
+ if (entry == STATIC_INVALID)
{
- handler_data *hdata = table[entry];
-
- /* if we hit a NULL hdata, then we need to allocate this one as a new one */
- if (hdata->handler.generic == NULL)
+ // two attempts to find an empty
+ for (int attempt = 0; attempt < 2; attempt++)
{
- hdata->handler.generic = handler;
- hdata->bytestart = bytestart;
- hdata->byteend = byteend;
- hdata->bytemask = bytemask;
- hdata->name = handler_name;
- hdata->object = object;
- return entry;
+ // scan all possible assigned entries for something unpopulated, or for an exact match
+ for (UINT8 scanentry = STATIC_COUNT; scanentry < SUBTABLE_BASE; scanentry++)
+ {
+ handler_entry &curentry = handler(scanentry);
+
+ // exact match takes precedence, and in fact doesn't need any
+ // further configuration or population
+ if (curentry.matches_exactly(bytestart, byteend, bytemask))
+ return scanentry;
+
+ // unpopulated is our second choice
+ if (entry == STATIC_INVALID && !curentry.populated())
+ entry = scanentry;
+ }
+
+ // if we didn't find anything, find something to depopulate
+ if (entry != STATIC_INVALID)
+ break;
+ depopulate_unused();
}
- /* if we find a perfect match, return a duplicate entry */
- if (hdata->handler.generic == handler && hdata->bytestart == bytestart && hdata->bytemask == bytemask && hdata->object == object)
- return entry;
+ // if we utterly failed, it's fatal
+ if (entry == STATIC_INVALID)
+ throw emu_fatalerror("Out of handler entries in address table");
}
- return 0;
-}
-
-
-/*-------------------------------------------------
- table_compute_subhandler - compute data for
- a subhandler
--------------------------------------------------*/
-
-static void table_compute_subhandler(handler_data **table, UINT8 entry, read_or_write readorwrite, int spacebits, int spaceendian, int handlerbits, int handlerunitmask)
-{
- int maxunits = spacebits / handlerbits;
- handler_data *hdata = table[entry];
- int unitnum;
-
- assert_always(!HANDLER_IS_STATIC(entry), "table_compute_subhandler called with static handlers and mismatched data bus widths");
-
- /* copy raw data to the subhandler data */
- hdata->subobject = hdata->object;
- hdata->subhandler = hdata->handler;
- /* fill in a stub as the real handler */
- hdata->object = hdata;
- hdata->handler = get_stub_handler(readorwrite, spacebits, handlerbits);
+ // configure the entry to our parameters
+ handler_entry &curentry = handler(entry);
+ curentry.configure(bytestart, byteend, bytemask);
- /* compute the number of subunits */
- hdata->subunits = 0;
- for (unitnum = 0; unitnum < maxunits; unitnum++)
- if (handlerunitmask & (1 << unitnum))
- hdata->subunits++;
- assert_always(hdata->subunits > 0, "table_compute_subhandler called with no bytes specified in mask");
-
- /* then fill in the shifts based on the endianness */
- if (spaceendian == ENDIANNESS_LITTLE)
- {
- UINT8 *unitshift = &hdata->subshift[0];
- for (unitnum = 0; unitnum < maxunits; unitnum++)
- if (handlerunitmask & (1 << unitnum))
- *unitshift++ = unitnum * handlerbits;
- }
- else
- {
- UINT8 *unitshift = &hdata->subshift[hdata->subunits];
- for (unitnum = 0; unitnum < maxunits; unitnum++)
- if (handlerunitmask & (1 << unitnum))
- *--unitshift = unitnum * handlerbits;
- }
+ // populate it
+ populate_range_mirrored(bytestart, byteend, bytemirror, entry);
+
+ // recompute any direct access on this space if it is a read modification
+ m_space.m_direct.force_update(entry);
+ return entry;
}
-/*-------------------------------------------------
- table_populate_range - assign a memory handler
- to a range of addresses
--------------------------------------------------*/
+//-------------------------------------------------
+// populate_range - assign a memory handler to a
+// range of addresses
+//-------------------------------------------------
-static void table_populate_range(address_table *tabledata, offs_t bytestart, offs_t byteend, UINT8 handler)
+void address_table::populate_range(offs_t bytestart, offs_t byteend, UINT8 handlerindex)
{
- offs_t l2mask = (1 << LEVEL2_BITS) - 1;
- offs_t l1start = bytestart >> LEVEL2_BITS;
+ offs_t l2mask = (1 << level2_bits()) - 1;
+ offs_t l1start = bytestart >> level2_bits();
offs_t l2start = bytestart & l2mask;
- offs_t l1stop = byteend >> LEVEL2_BITS;
+ offs_t l1stop = byteend >> level2_bits();
offs_t l2stop = byteend & l2mask;
- offs_t l1index;
- /* sanity check */
+ // sanity check
if (bytestart > byteend)
return;
- /* handle the starting edge if it's not on a block boundary */
+ // handle the starting edge if it's not on a block boundary
if (l2start != 0)
{
- UINT8 *subtable = subtable_open(tabledata, l1start);
+ UINT8 *subtable = subtable_open(l1start);
- /* if the start and stop end within the same block, handle that */
+ // if the start and stop end within the same block, handle that
if (l1start == l1stop)
{
- memset(&subtable[l2start], handler, l2stop - l2start + 1);
- subtable_close(tabledata, l1start);
+ memset(&subtable[l2start], handlerindex, l2stop - l2start + 1);
+ subtable_close(l1start);
return;
}
- /* otherwise, fill until the end */
- memset(&subtable[l2start], handler, (1 << LEVEL2_BITS) - l2start);
- subtable_close(tabledata, l1start);
- if (l1start != (offs_t)~0) l1start++;
+ // otherwise, fill until the end
+ memset(&subtable[l2start], handlerindex, (1 << level2_bits()) - l2start);
+ subtable_close(l1start);
+ if (l1start != (offs_t)~0)
+ l1start++;
}
- /* handle the trailing edge if it's not on a block boundary */
+ // handle the trailing edge if it's not on a block boundary
if (l2stop != l2mask)
{
- UINT8 *subtable = subtable_open(tabledata, l1stop);
+ UINT8 *subtable = subtable_open(l1stop);
- /* fill from the beginning */
- memset(&subtable[0], handler, l2stop + 1);
- subtable_close(tabledata, l1stop);
+ // fill from the beginning
+ memset(&subtable[0], handlerindex, l2stop + 1);
+ subtable_close(l1stop);
- /* if the start and stop end within the same block, handle that */
+ // if the start and stop end within the same block, handle that
if (l1start == l1stop)
return;
- if (l1stop != 0) l1stop--;
+ if (l1stop != 0)
+ l1stop--;
}
- /* now fill in the middle tables */
- for (l1index = l1start; l1index <= l1stop; l1index++)
+ // now fill in the middle tables
+ for (offs_t l1index = l1start; l1index <= l1stop; l1index++)
{
- /* if we have a subtable here, release it */
- if (tabledata->table[l1index] >= SUBTABLE_BASE)
- subtable_release(tabledata, tabledata->table[l1index]);
- tabledata->table[l1index] = handler;
+ // if we have a subtable here, release it
+ if (m_table[l1index] >= SUBTABLE_BASE)
+ subtable_release(m_table[l1index]);
+ m_table[l1index] = handlerindex;
}
}
-/*-------------------------------------------------
- table_populate_range_mirrored - assign a
- memory handler to a range of addresses
- including mirrors
--------------------------------------------------*/
+//-------------------------------------------------
+// populate_range_mirrored - assign a memory
+// handler to a range of addresses including
+// mirrors
+//-------------------------------------------------
-static void table_populate_range_mirrored(address_space *space, address_table *tabledata, offs_t bytestart, offs_t byteend, offs_t bytemirror, UINT8 handler)
+void address_table::populate_range_mirrored(offs_t bytestart, offs_t byteend, offs_t bytemirror, UINT8 handlerindex)
{
- offs_t lmirrorbit[LEVEL2_BITS], lmirrorbits, hmirrorbit[32 - LEVEL2_BITS], hmirrorbits, lmirrorcount, hmirrorcount;
+ // determine the mirror bits
+ offs_t lmirrorbits = 0;
+ offs_t lmirrorbit[32];
+ for (int bit = 0; bit < level2_bits(); bit++)
+ if (bytemirror & (1 << bit))
+ lmirrorbit[lmirrorbits++] = 1 << bit;
+
+ offs_t hmirrorbits = 0;
+ offs_t hmirrorbit[32];
+ for (int bit = level2_bits(); bit < 32; bit++)
+ if (bytemirror & (1 << bit))
+ hmirrorbit[hmirrorbits++] = 1 << bit;
+
+ // loop over mirrors in the level 2 table
UINT8 prev_entry = STATIC_INVALID;
- int cur_index, prev_index = 0;
- int i;
-
- /* determine the mirror bits */
- hmirrorbits = lmirrorbits = 0;
- for (i = 0; i < LEVEL2_BITS; i++)
- if (bytemirror & (1 << i))
- lmirrorbit[lmirrorbits++] = 1 << i;
- for (i = LEVEL2_BITS; i < 32; i++)
- if (bytemirror & (1 << i))
- hmirrorbit[hmirrorbits++] = 1 << i;
-
- /* loop over mirrors in the level 2 table */
- for (hmirrorcount = 0; hmirrorcount < (1 << hmirrorbits); hmirrorcount++)
+ int prev_index = 0;
+ for (offs_t hmirrorcount = 0; hmirrorcount < (1 << hmirrorbits); hmirrorcount++)
{
- /* compute the base of this mirror */
+ // compute the base of this mirror
offs_t hmirrorbase = 0;
- for (i = 0; i < hmirrorbits; i++)
- if (hmirrorcount & (1 << i))
- hmirrorbase |= hmirrorbit[i];
+ for (int bit = 0; bit < hmirrorbits; bit++)
+ if (hmirrorcount & (1 << bit))
+ hmirrorbase |= hmirrorbit[bit];
- /* invalidate any intersecting cached ranges */
- for (lmirrorcount = 0; lmirrorcount < (1 << lmirrorbits); lmirrorcount++)
+ // invalidate any intersecting cached ranges
+ for (offs_t lmirrorcount = 0; lmirrorcount < (1 << lmirrorbits); lmirrorcount++)
{
- /* compute the base of this mirror */
+ // compute the base of this mirror
offs_t lmirrorbase = hmirrorbase;
- for (i = 0; i < lmirrorbits; i++)
- if (lmirrorcount & (1 << i))
- lmirrorbase |= lmirrorbit[i];
- direct_range_remove_intersecting(space, bytestart + lmirrorbase, byteend + lmirrorbase);
+ for (int bit = 0; bit < lmirrorbits; bit++)
+ if (lmirrorcount & (1 << bit))
+ lmirrorbase |= lmirrorbit[bit];
+ m_space.m_direct.remove_intersecting_ranges(bytestart + lmirrorbase, byteend + lmirrorbase);
}
- /* if this is not our first time through, and the level 2 entry matches the previous
- level 2 entry, just do a quick map and get out; note that this only works for entries
- which don't span multiple level 1 table entries */
- cur_index = LEVEL1_INDEX(bytestart + hmirrorbase);
- if (cur_index == LEVEL1_INDEX(byteend + hmirrorbase))
+ // if this is not our first time through, and the level 2 entry matches the previous
+ // level 2 entry, just do a quick map and get out; note that this only works for entries
+ // which don't span multiple level 1 table entries
+ int cur_index = level1_index(bytestart + hmirrorbase);
+ if (cur_index == level1_index(byteend + hmirrorbase))
{
- if (hmirrorcount != 0 && prev_entry == tabledata->table[cur_index])
+ if (hmirrorcount != 0 && prev_entry == m_table[cur_index])
{
- VPRINTF(("Quick mapping subtable at %08X to match subtable at %08X\n", cur_index << LEVEL2_BITS, prev_index << LEVEL2_BITS));
+ VPRINTF(("Quick mapping subtable at %08X to match subtable at %08X\n", cur_index << level2_bits(), prev_index << level2_bits()));
- /* release the subtable if the old value was a subtable */
- if (tabledata->table[cur_index] >= SUBTABLE_BASE)
- subtable_release(tabledata, tabledata->table[cur_index]);
+ // release the subtable if the old value was a subtable
+ if (m_table[cur_index] >= SUBTABLE_BASE)
+ subtable_release(m_table[cur_index]);
- /* reallocate the subtable if the new value is a subtable */
- if (tabledata->table[prev_index] >= SUBTABLE_BASE)
- subtable_realloc(tabledata, tabledata->table[prev_index]);
+ // reallocate the subtable if the new value is a subtable
+ if (m_table[prev_index] >= SUBTABLE_BASE)
+ subtable_realloc(m_table[prev_index]);
- /* set the new value and short-circuit the mapping step */
- tabledata->table[cur_index] = tabledata->table[prev_index];
+ // set the new value and short-circuit the mapping step
+ m_table[cur_index] = m_table[prev_index];
continue;
}
prev_index = cur_index;
- prev_entry = tabledata->table[cur_index];
+ prev_entry = m_table[cur_index];
}
- /* loop over mirrors in the level 1 table */
- for (lmirrorcount = 0; lmirrorcount < (1 << lmirrorbits); lmirrorcount++)
+ // loop over mirrors in the level 1 table
+ for (offs_t lmirrorcount = 0; lmirrorcount < (1 << lmirrorbits); lmirrorcount++)
{
- /* compute the base of this mirror */
+ // compute the base of this mirror
offs_t lmirrorbase = hmirrorbase;
- for (i = 0; i < lmirrorbits; i++)
- if (lmirrorcount & (1 << i))
- lmirrorbase |= lmirrorbit[i];
+ for (int bit = 0; bit < lmirrorbits; bit++)
+ if (lmirrorcount & (1 << bit))
+ lmirrorbase |= lmirrorbit[bit];
- /* populate the tables */
- table_populate_range(tabledata, bytestart + lmirrorbase, byteend + lmirrorbase, handler);
+ // populate the tables
+ populate_range(bytestart + lmirrorbase, byteend + lmirrorbase, handlerindex);
}
}
}
-/*-------------------------------------------------
- table_derive_range - look up the entry for
- a memory range, and then compute the extent
- of that range based on the lookup tables
--------------------------------------------------*/
+//-------------------------------------------------
+// depopulate_unused - scan the table and
+// eliminate entries that are no longer used
+//-------------------------------------------------
-static UINT8 table_derive_range(const address_table *table, offs_t byteaddress, offs_t *bytestart, offs_t *byteend)
+void address_table::depopulate_unused()
{
- UINT32 curentry, entry, curl1entry, l1entry;
- const handler_data *handler;
- offs_t minscan, maxscan;
+ assert(false);
+}
- /* look up the initial address to get the entry we care about */
- entry = l1entry = table->table[LEVEL1_INDEX(byteaddress)];
+
+//-------------------------------------------------
+// derive_range - look up the entry for a memory
+// range, and then compute the extent of that
+// range based on the lookup tables
+//-------------------------------------------------
+
+UINT8 address_table::derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &byteend) const
+{
+ // look up the initial address to get the entry we care about
+ UINT8 l1entry;
+ UINT8 entry = l1entry = m_table[level1_index(byteaddress)];
if (l1entry >= SUBTABLE_BASE)
- entry = table->table[LEVEL2_INDEX(l1entry, byteaddress)];
- handler = table->handlers[entry];
+ entry = m_table[level2_index(l1entry, byteaddress)];
- /* use the bytemask of the entry to set minimum and maximum bounds */
- minscan = handler->bytestart | ((byteaddress - handler->bytestart) & ~handler->bytemask);
- maxscan = handler->byteend | ((byteaddress - handler->bytestart) & ~handler->bytemask);
+ // use the bytemask of the entry to set minimum and maximum bounds
+ offs_t minscan, maxscan;
+ handler(entry).mirrored_start_end(byteaddress, minscan, maxscan);
- /* first scan backwards to find the start address */
- curl1entry = l1entry;
- curentry = entry;
- *bytestart = byteaddress;
+ // first scan backwards to find the start address
+ UINT8 curl1entry = l1entry;
+ UINT8 curentry = entry;
+ bytestart = byteaddress;
while (1)
{
- /* if we need to scan the subtable, do it */
+ // if we need to scan the subtable, do it
if (curentry != curl1entry)
{
- UINT32 minindex = LEVEL2_INDEX(curl1entry, 0);
+ UINT32 minindex = level2_index(curl1entry, 0);
UINT32 index;
- /* scan backwards from the current address, until the previous entry doesn't match */
- for (index = LEVEL2_INDEX(curl1entry, *bytestart); index > minindex; index--, *bytestart -= 1)
- if (table->table[index - 1] != entry)
+ // scan backwards from the current address, until the previous entry doesn't match
+ for (index = level2_index(curl1entry, bytestart); index > minindex; index--, bytestart -= 1)
+ if (m_table[index - 1] != entry)
break;
- /* if we didn't hit the beginning, then we're finished scanning */
+ // if we didn't hit the beginning, then we're finished scanning
if (index != minindex)
break;
}
- /* move to the beginning of this L1 entry; stop at the minimum address */
- *bytestart &= ~((1 << LEVEL2_BITS) - 1);
- if (*bytestart <= minscan)
+ // move to the beginning of this L1 entry; stop at the minimum address
+ bytestart &= ~((1 << level2_bits()) - 1);
+ if (bytestart <= minscan)
break;
- /* look up the entry of the byte at the end of the previous L1 entry; if it doesn't match, stop */
- curentry = curl1entry = table->table[LEVEL1_INDEX(*bytestart - 1)];
+ // look up the entry of the byte at the end of the previous L1 entry; if it doesn't match, stop
+ curentry = curl1entry = m_table[level1_index(bytestart - 1)];
if (curl1entry >= SUBTABLE_BASE)
- curentry = table->table[LEVEL2_INDEX(curl1entry, *bytestart - 1)];
+ curentry = m_table[level2_index(curl1entry, bytestart - 1)];
if (curentry != entry)
break;
- /* move into the previous entry and resume searching */
- *bytestart -= 1;
+ // move into the previous entry and resume searching
+ bytestart -= 1;
}
- /* then scan forwards to find the end address */
+ // then scan forwards to find the end address
curl1entry = l1entry;
curentry = entry;
- *byteend = byteaddress;
+ byteend = byteaddress;
while (1)
{
- /* if we need to scan the subtable, do it */
+ // if we need to scan the subtable, do it
if (curentry != curl1entry)
{
- UINT32 maxindex = LEVEL2_INDEX(curl1entry, ~0);
+ UINT32 maxindex = level2_index(curl1entry, ~0);
UINT32 index;
- /* scan forwards from the current address, until the next entry doesn't match */
- for (index = LEVEL2_INDEX(curl1entry, *byteend); index < maxindex; index++, *byteend += 1)
- if (table->table[index + 1] != entry)
+ // scan forwards from the current address, until the next entry doesn't match
+ for (index = level2_index(curl1entry, byteend); index < maxindex; index++, byteend += 1)
+ if (m_table[index + 1] != entry)
break;
- /* if we didn't hit the end, then we're finished scanning */
+ // if we didn't hit the end, then we're finished scanning
if (index != maxindex)
break;
}
- /* move to the end of this L1 entry; stop at the maximum address */
- *byteend |= (1 << LEVEL2_BITS) - 1;
- if (*byteend >= maxscan)
+ // move to the end of this L1 entry; stop at the maximum address
+ byteend |= (1 << level2_bits()) - 1;
+ if (byteend >= maxscan)
break;
- /* look up the entry of the byte at the start of the next L1 entry; if it doesn't match, stop */
- curentry = curl1entry = table->table[LEVEL1_INDEX(*byteend + 1)];
+ // look up the entry of the byte at the start of the next L1 entry; if it doesn't match, stop
+ curentry = curl1entry = m_table[level1_index(byteend + 1)];
if (curl1entry >= SUBTABLE_BASE)
- curentry = table->table[LEVEL2_INDEX(curl1entry, *byteend + 1)];
+ curentry = m_table[level2_index(curl1entry, byteend + 1)];
if (curentry != entry)
break;
- /* move into the next entry and resume searching */
- *byteend += 1;
+ // move into the next entry and resume searching
+ byteend += 1;
}
return entry;
}
+//-------------------------------------------------
+// mask_all_handlers - apply a mask to all
+// address handlers
+//-------------------------------------------------
-/***************************************************************************
- SUBTABLE MANAGEMENT
-***************************************************************************/
+void address_table::mask_all_handlers(offs_t mask)
+{
+ // we don't loop over map entries because the mask applies to static handlers as well
+ for (int entrynum = 0; entrynum < ENTRY_COUNT; entrynum++)
+ handler(entrynum).apply_mask(mask);
+}
-/*-------------------------------------------------
- subtable_alloc - allocate a fresh subtable
- and set its usecount to 1
--------------------------------------------------*/
-static UINT8 subtable_alloc(address_table *tabledata)
+
+//**************************************************************************
+// SUBTABLE MANAGEMENT
+//**************************************************************************
+
+//-------------------------------------------------
+// subtable_alloc - allocate a fresh subtable
+// and set its usecount to 1
+//-------------------------------------------------
+
+UINT8 address_table::subtable_alloc()
{
- /* loop */
+ // loop
while (1)
{
- UINT8 subindex;
-
- /* find a subtable with a usecount of 0 */
- for (subindex = 0; subindex < SUBTABLE_COUNT; subindex++)
- if (tabledata->subtable[subindex].usecount == 0)
+ // find a subtable with a usecount of 0
+ for (UINT8 subindex = 0; subindex < SUBTABLE_COUNT; subindex++)
+ if (m_subtable[subindex].m_usecount == 0)
{
- /* if this is past our allocation budget, allocate some more */
- if (subindex >= tabledata->subtable_alloc)
+ // if this is past our allocation budget, allocate some more
+ if (subindex >= m_subtable_alloc)
{
- UINT32 oldsize = (1 << LEVEL1_BITS) + (tabledata->subtable_alloc << LEVEL2_BITS);
- tabledata->subtable_alloc += SUBTABLE_ALLOC;
- UINT32 newsize = (1 << LEVEL1_BITS) + (tabledata->subtable_alloc << LEVEL2_BITS);
-
- UINT8 *newtable = auto_alloc_array(tabledata->machine, UINT8, newsize);
- memcpy(newtable, tabledata->table, oldsize);
- auto_free(tabledata->machine, tabledata->table);
- tabledata->table = newtable;
+ UINT32 oldsize = (1 << LEVEL1_BITS) + (m_subtable_alloc << level2_bits());
+ m_subtable_alloc += SUBTABLE_ALLOC;
+ UINT32 newsize = (1 << LEVEL1_BITS) + (m_subtable_alloc << level2_bits());
+
+ UINT8 *newtable = auto_alloc_array_clear(&m_space.m_machine, UINT8, newsize);
+ memcpy(newtable, m_table, oldsize);
+ if (m_live_lookup == m_table)
+ m_live_lookup = newtable;
+ auto_free(&m_space.m_machine, m_table);
+ m_table = newtable;
}
- /* bump the usecount and return */
- tabledata->subtable[subindex].usecount++;
+ // bump the usecount and return
+ m_subtable[subindex].m_usecount++;
return subindex + SUBTABLE_BASE;
}
- /* merge any subtables we can */
- if (!subtable_merge(tabledata))
+ // merge any subtables we can
+ if (!subtable_merge())
fatalerror("Ran out of subtables!");
}
}
-/*-------------------------------------------------
- subtable_realloc - increment the usecount on
- a subtable
--------------------------------------------------*/
+//-------------------------------------------------
+// subtable_realloc - increment the usecount on
+// a subtable
+//-------------------------------------------------
-static void subtable_realloc(address_table *tabledata, UINT8 subentry)
+void address_table::subtable_realloc(UINT8 subentry)
{
UINT8 subindex = subentry - SUBTABLE_BASE;
- /* sanity check */
- if (tabledata->subtable[subindex].usecount <= 0)
+ // sanity check
+ if (m_subtable[subindex].m_usecount <= 0)
fatalerror("Called subtable_realloc on a table with a usecount of 0");
- /* increment the usecount */
- tabledata->subtable[subindex].usecount++;
+ // increment the usecount
+ m_subtable[subindex].m_usecount++;
}
-/*-------------------------------------------------
- subtable_merge - merge any duplicate
- subtables
--------------------------------------------------*/
+//-------------------------------------------------
+// subtable_merge - merge any duplicate
+// subtables
+//-------------------------------------------------
-static int subtable_merge(address_table *tabledata)
+int address_table::subtable_merge()
{
int merged = 0;
UINT8 subindex;
VPRINTF(("Merging subtables....\n"));
- /* okay, we failed; update all the checksums and merge tables */
+ // okay, we failed; update all the checksums and merge tables
for (subindex = 0; subindex < SUBTABLE_COUNT; subindex++)
- if (!tabledata->subtable[subindex].checksum_valid && tabledata->subtable[subindex].usecount != 0)
+ if (!m_subtable[subindex].m_checksum_valid && m_subtable[subindex].m_usecount != 0)
{
- UINT32 *subtable = (UINT32 *)SUBTABLE_PTR(tabledata, subindex + SUBTABLE_BASE);
+ UINT32 *subtable = reinterpret_cast<UINT32 *>(subtable_ptr(subindex + SUBTABLE_BASE));
UINT32 checksum = 0;
- int l2index;
- /* update the checksum */
- for (l2index = 0; l2index < (1 << LEVEL2_BITS)/4; l2index++)
+ // update the checksum
+ for (int l2index = 0; l2index < (1 << level2_bits())/4; l2index++)
checksum += subtable[l2index];
- tabledata->subtable[subindex].checksum = checksum;
- tabledata->subtable[subindex].checksum_valid = 1;
+ m_subtable[subindex].m_checksum = checksum;
+ m_subtable[subindex].m_checksum_valid = true;
}
- /* see if there's a matching checksum */
+ // see if there's a matching checksum
for (subindex = 0; subindex < SUBTABLE_COUNT; subindex++)
- if (tabledata->subtable[subindex].usecount != 0)
+ if (m_subtable[subindex].m_usecount != 0)
{
- UINT8 *subtable = SUBTABLE_PTR(tabledata, subindex + SUBTABLE_BASE);
- UINT32 checksum = tabledata->subtable[subindex].checksum;
+ UINT8 *subtable = subtable_ptr(subindex + SUBTABLE_BASE);
+ UINT32 checksum = m_subtable[subindex].m_checksum;
UINT8 sumindex;
for (sumindex = subindex + 1; sumindex < SUBTABLE_COUNT; sumindex++)
- if (tabledata->subtable[sumindex].usecount != 0 &&
- tabledata->subtable[sumindex].checksum == checksum &&
- !memcmp(subtable, SUBTABLE_PTR(tabledata, sumindex + SUBTABLE_BASE), 1 << LEVEL2_BITS))
+ if (m_subtable[sumindex].m_usecount != 0 &&
+ m_subtable[sumindex].m_checksum == checksum &&
+ !memcmp(subtable, subtable_ptr(sumindex + SUBTABLE_BASE), 1 << level2_bits()))
{
int l1index;
VPRINTF(("Merging subtable %d and %d....\n", subindex, sumindex));
- /* find all the entries in the L1 tables that pointed to the old one, and point them to the merged table */
- for (l1index = 0; l1index <= (0xffffffffUL >> LEVEL2_BITS); l1index++)
- if (tabledata->table[l1index] == sumindex + SUBTABLE_BASE)
+ // find all the entries in the L1 tables that pointed to the old one, and point them to the merged table
+ for (l1index = 0; l1index <= (0xffffffffUL >> level2_bits()); l1index++)
+ if (m_table[l1index] == sumindex + SUBTABLE_BASE)
{
- subtable_release(tabledata, sumindex + SUBTABLE_BASE);
- subtable_realloc(tabledata, subindex + SUBTABLE_BASE);
- tabledata->table[l1index] = subindex + SUBTABLE_BASE;
+ subtable_release(sumindex + SUBTABLE_BASE);
+ subtable_realloc(subindex + SUBTABLE_BASE);
+ m_table[l1index] = subindex + SUBTABLE_BASE;
merged++;
}
}
@@ -2857,499 +3143,87 @@ static int subtable_merge(address_table *tabledata)
}
-/*-------------------------------------------------
- subtable_release - decrement the usecount on
- a subtable and free it if we're done
--------------------------------------------------*/
+//-------------------------------------------------
+// subtable_release - decrement the usecount on
+// a subtable and free it if we're done
+//-------------------------------------------------
-static void subtable_release(address_table *tabledata, UINT8 subentry)
+void address_table::subtable_release(UINT8 subentry)
{
UINT8 subindex = subentry - SUBTABLE_BASE;
- /* sanity check */
- if (tabledata->subtable[subindex].usecount <= 0)
+ // sanity check
+ if (m_subtable[subindex].m_usecount <= 0)
fatalerror("Called subtable_release on a table with a usecount of 0");
- /* decrement the usecount and clear the checksum if we're at 0 */
- tabledata->subtable[subindex].usecount--;
- if (tabledata->subtable[subindex].usecount == 0)
- tabledata->subtable[subindex].checksum = 0;
+ // decrement the usecount and clear the checksum if we're at 0
+ m_subtable[subindex].m_usecount--;
+ if (m_subtable[subindex].m_usecount == 0)
+ m_subtable[subindex].m_checksum = 0;
}
-/*-------------------------------------------------
- subtable_open - gain access to a subtable for
- modification
--------------------------------------------------*/
+//-------------------------------------------------
+// subtable_open - gain access to a subtable for
+// modification
+//-------------------------------------------------
-static UINT8 *subtable_open(address_table *tabledata, offs_t l1index)
+UINT8 *address_table::subtable_open(offs_t l1index)
{
- UINT8 subentry = tabledata->table[l1index];
+ UINT8 subentry = m_table[l1index];
- /* if we don't have a subtable yet, allocate a new one */
+ // if we don't have a subtable yet, allocate a new one
if (subentry < SUBTABLE_BASE)
{
- UINT8 newentry = subtable_alloc(tabledata);
- memset(SUBTABLE_PTR(tabledata, newentry), subentry, 1 << LEVEL2_BITS);
- tabledata->table[l1index] = newentry;
- tabledata->subtable[newentry - SUBTABLE_BASE].checksum = (subentry + (subentry << 8) + (subentry << 16) + (subentry << 24)) * ((1 << LEVEL2_BITS)/4);
+ UINT8 newentry = subtable_alloc();
+ memset(subtable_ptr(newentry), subentry, 1 << level2_bits());
+ m_table[l1index] = newentry;
+ m_subtable[newentry - SUBTABLE_BASE].m_checksum = (subentry + (subentry << 8) + (subentry << 16) + (subentry << 24)) * ((1 << level2_bits())/4);
subentry = newentry;
}
- /* if we're sharing this subtable, we also need to allocate a fresh copy */
- else if (tabledata->subtable[subentry - SUBTABLE_BASE].usecount > 1)
+ // if we're sharing this subtable, we also need to allocate a fresh copy
+ else if (m_subtable[subentry - SUBTABLE_BASE].m_usecount > 1)
{
- UINT8 newentry = subtable_alloc(tabledata);
+ UINT8 newentry = subtable_alloc();
- /* allocate may cause some additional merging -- look up the subentry again */
- /* when we're done; it should still require a split */
- subentry = tabledata->table[l1index];
+ // allocate may cause some additional merging -- look up the subentry again
+ // when we're done; it should still require a split
+ subentry = m_table[l1index];
assert(subentry >= SUBTABLE_BASE);
- assert(tabledata->subtable[subentry - SUBTABLE_BASE].usecount > 1);
+ assert(m_subtable[subentry - SUBTABLE_BASE].m_usecount > 1);
- memcpy(SUBTABLE_PTR(tabledata, newentry), SUBTABLE_PTR(tabledata, subentry), 1 << LEVEL2_BITS);
- subtable_release(tabledata, subentry);
- tabledata->table[l1index] = newentry;
- tabledata->subtable[newentry - SUBTABLE_BASE].checksum = tabledata->subtable[subentry - SUBTABLE_BASE].checksum;
+ memcpy(subtable_ptr(newentry), subtable_ptr(subentry), 1 << level2_bits());
+ subtable_release(subentry);
+ m_table[l1index] = newentry;
+ m_subtable[newentry - SUBTABLE_BASE].m_checksum = m_subtable[subentry - SUBTABLE_BASE].m_checksum;
subentry = newentry;
}
- /* mark the table dirty */
- tabledata->subtable[subentry - SUBTABLE_BASE].checksum_valid = 0;
-
- /* return the pointer to the subtable */
- return SUBTABLE_PTR(tabledata, subentry);
-}
-
-
-/*-------------------------------------------------
- subtable_close - stop access to a subtable
--------------------------------------------------*/
-
-static void subtable_close(address_table *tabledata, offs_t l1index)
-{
- /* defer any merging until we run out of tables */
-}
-
-
-
-/***************************************************************************
- DIRECT MEMORY RANGES
-***************************************************************************/
-
-/*-------------------------------------------------
- direct_range_find - find a byte address in
- a range
--------------------------------------------------*/
-
-static direct_range *direct_range_find(address_space *space, offs_t byteaddress, UINT8 *entry)
-{
- direct_range **rangelistptr;
- direct_range **rangeptr;
- direct_range *range;
-
- /* determine which entry */
- byteaddress &= space->bytemask;
- *entry = space->read.table[LEVEL1_INDEX(byteaddress)];
- if (*entry >= SUBTABLE_BASE)
- *entry = space->read.table[LEVEL2_INDEX(*entry, byteaddress)];
- rangelistptr = &space->direct.rangelist[*entry];
-
- /* scan our table */
- for (rangeptr = rangelistptr; *rangeptr != NULL; rangeptr = &(*rangeptr)->next)
- if (byteaddress >= (*rangeptr)->bytestart && byteaddress <= (*rangeptr)->byteend)
- {
- /* found a match; move us to the head of the list if we're not already there */
- range = *rangeptr;
- if (range != *rangelistptr)
- {
- *rangeptr = range->next;
- range->next = *rangelistptr;
- *rangelistptr = range;
- }
- return range;
- }
-
- /* didn't find out; allocate a new one */
- range = space->direct.freerangelist;
- if (range != NULL)
- space->direct.freerangelist = range->next;
- else
- range = auto_alloc(space->machine, direct_range);
-
- /* fill in the range */
- table_derive_range(&space->read, byteaddress, &range->bytestart, &range->byteend);
- range->next = *rangelistptr;
- *rangelistptr = range;
-
- return range;
-}
-
-
-/*-------------------------------------------------
- direct_range_remove_intersecting - remove
- all cached ranges that intersect the given
- address range
--------------------------------------------------*/
-
-static void direct_range_remove_intersecting(address_space *space, offs_t bytestart, offs_t byteend)
-{
- int entry;
-
- /* loop over all entries */
- for (entry = 0; entry < ARRAY_LENGTH(space->read.handlers); entry++)
- {
- direct_range **rangeptr, **nextrangeptr;
-
- /* loop over all ranges in this entry's list */
- for (nextrangeptr = rangeptr = &space->direct.rangelist[entry]; *rangeptr != NULL; rangeptr = nextrangeptr)
- {
- /* if we intersect, remove and add to the free range list */
- if (bytestart <= (*rangeptr)->byteend && byteend >= (*rangeptr)->bytestart)
- {
- direct_range *range = *rangeptr;
- *rangeptr = range->next;
- range->next = space->direct.freerangelist;
- space->direct.freerangelist = range;
- }
-
- /* otherwise advance to the next in the list */
- else
- nextrangeptr = &(*rangeptr)->next;
- }
- }
-}
-
-
-
-/***************************************************************************
- MEMORY BLOCK ALLOCATION
-***************************************************************************/
-
-/*-------------------------------------------------
- block_allocate - allocate a single
- memory block of data
--------------------------------------------------*/
-
-static void *block_allocate(const address_space *space, offs_t bytestart, offs_t byteend, void *memory)
-{
- memory_private *memdata = space->machine->memory_data;
- int allocatemem = (memory == NULL);
- memory_block *block;
- size_t bytestoalloc;
- const region_info *region;
-
- VPRINTF(("block_allocate('%s',%s,%08X,%08X,%p)\n", space->cpu->tag(), space->name, bytestart, byteend, memory));
-
- /* determine how much memory to allocate for this */
- bytestoalloc = sizeof(*block);
- if (allocatemem)
- bytestoalloc += byteend - bytestart + 1;
-
- /* allocate and clear the memory */
- block = (memory_block *)auto_alloc_array_clear(space->machine, UINT8, bytestoalloc);
- if (allocatemem)
- memory = block + 1;
-
- /* register for saving, but only if we're not part of a memory region */
- for (region = space->machine->m_regionlist.first(); region != NULL; region = region->next())
- {
- if ((UINT8 *)memory >= region->base() && ((UINT8 *)memory + (byteend - bytestart + 1)) < region->end())
- {
- VPRINTF(("skipping save of this memory block as it is covered by a memory region\n"));
- break;
- }
- }
-
- /* if we didn't find a match, register */
- if (region == NULL)
- {
- int bytes_per_element = space->dbits/8;
- char name[256];
-
- sprintf(name, "%08x-%08x", bytestart, byteend);
- state_save_register_memory(space->machine, "memory", space->cpu->tag(), space->spacenum, name, memory, bytes_per_element, (UINT32)(byteend - bytestart + 1) / bytes_per_element, __FILE__, __LINE__);
- }
-
- /* fill in the tracking block */
- block->space = space;
- block->isallocated = allocatemem;
- block->bytestart = bytestart;
- block->byteend = byteend;
- block->data = (UINT8 *)memory;
-
- /* attach us to the head of the list */
- block->next = memdata->memory_block_list;
- memdata->memory_block_list = block;
-
- return memory;
-}
-
-
-/*-------------------------------------------------
- block_assign_intersecting - find all
- intersecting blocks and assign their pointers
--------------------------------------------------*/
-
-static address_map_entry *block_assign_intersecting(address_space *space, offs_t bytestart, offs_t byteend, UINT8 *base)
-{
- memory_private *memdata = space->machine->memory_data;
- address_map_entry *entry, *unassigned = NULL;
-
- /* loop over the adjusted map and assign memory to any blocks we can */
- for (entry = space->map->m_entrylist; entry != NULL; entry = entry->m_next)
- {
- /* if we haven't assigned this block yet, see if we have a mapped shared pointer for it */
- if (entry->m_memory == NULL && entry->m_share != NULL)
- {
- void *shareptr = memdata->sharemap.find(entry->m_share);
- if (shareptr != UNMAPPED_SHARE_PTR)
- {
- entry->m_memory = shareptr;
- VPRINTF(("memory range %08X-%08X -> shared_ptr '%s' [%p]\n", entry->m_addrstart, entry->m_addrend, entry->m_share, entry->m_memory));
- }
- }
-
- /* otherwise, look for a match in this block */
- if (entry->m_memory == NULL && entry->m_bytestart >= bytestart && entry->m_byteend <= byteend)
- {
- entry->m_memory = base + (entry->m_bytestart - bytestart);
- VPRINTF(("memory range %08X-%08X -> found in block from %08X-%08X [%p]\n", entry->m_addrstart, entry->m_addrend, bytestart, byteend, entry->m_memory));
- }
-
- /* if we're the first match on a shared pointer, assign it now */
- if (entry->m_memory != NULL && entry->m_share != NULL)
- {
- void *shareptr = memdata->sharemap.find(entry->m_share);
- if (shareptr == UNMAPPED_SHARE_PTR)
- memdata->sharemap.add(entry->m_share, entry->m_memory, TRUE);
- }
-
- /* keep track of the first unassigned entry */
- if (entry->m_memory == NULL && unassigned == NULL && space_needs_backing_store(space, entry))
- unassigned = entry;
- }
-
- return unassigned;
-}
-
-
-
-/***************************************************************************
- INTERNAL HANDLERS
-***************************************************************************/
-
-/*-------------------------------------------------
- unmapped memory handlers
--------------------------------------------------*/
-
-static READ8_HANDLER( unmap_read8 )
-{
- if (space->log_unmap && !space->debugger_access) logerror("%s: unmapped %s memory byte read from %s\n", cpuexec_describe_context(space->machine), space->name, core_i64_hex_format(memory_byte_to_address(space, offset), space->addrchars));
- return space->unmap;
-}
-static READ16_HANDLER( unmap_read16 )
-{
- if (space->log_unmap && !space->debugger_access) logerror("%s: unmapped %s memory word read from %s & %04X\n", cpuexec_describe_context(space->machine), space->name, core_i64_hex_format(memory_byte_to_address(space, offset*2), space->addrchars), mem_mask);
- return space->unmap;
-}
-static READ32_HANDLER( unmap_read32 )
-{
- if (space->log_unmap && !space->debugger_access) logerror("%s: unmapped %s memory dword read from %s & %08X\n", cpuexec_describe_context(space->machine), space->name, core_i64_hex_format(memory_byte_to_address(space, offset*4), space->addrchars), mem_mask);
- return space->unmap;
-}
-static READ64_HANDLER( unmap_read64 )
-{
- if (space->log_unmap && !space->debugger_access) logerror("%s: unmapped %s memory qword read from %s & %s\n", cpuexec_describe_context(space->machine), space->name, core_i64_hex_format(memory_byte_to_address(space, offset*8), space->addrchars), core_i64_hex_format(mem_mask, 16));
- return space->unmap;
-}
-
-static WRITE8_HANDLER( unmap_write8 )
-{
- if (space->log_unmap && !space->debugger_access) logerror("%s: unmapped %s memory byte write to %s = %02X\n", cpuexec_describe_context(space->machine), space->name, core_i64_hex_format(memory_byte_to_address(space, offset), space->addrchars), data);
-}
-static WRITE16_HANDLER( unmap_write16 )
-{
- if (space->log_unmap && !space->debugger_access) logerror("%s: unmapped %s memory word write to %s = %04X & %04X\n", cpuexec_describe_context(space->machine), space->name, core_i64_hex_format(memory_byte_to_address(space, offset*2), space->addrchars), data, mem_mask);
-}
-static WRITE32_HANDLER( unmap_write32 )
-{
- if (space->log_unmap && !space->debugger_access) logerror("%s: unmapped %s memory dword write to %s = %08X & %08X\n", cpuexec_describe_context(space->machine), space->name, core_i64_hex_format(memory_byte_to_address(space, offset*4), space->addrchars), data, mem_mask);
-}
-static WRITE64_HANDLER( unmap_write64 )
-{
- if (space->log_unmap && !space->debugger_access) logerror("%s: unmapped %s memory qword write to %s = %s & %s\n", cpuexec_describe_context(space->machine), space->name, core_i64_hex_format(memory_byte_to_address(space, offset*8), space->addrchars), core_i64_hex_format(data, 16), core_i64_hex_format(mem_mask, 16));
-}
-
-
-/*-------------------------------------------------
- no-op memory handlers
--------------------------------------------------*/
-
-static READ8_HANDLER( nop_read8 ) { return space->unmap; }
-static READ16_HANDLER( nop_read16 ) { return space->unmap; }
-static READ32_HANDLER( nop_read32 ) { return space->unmap; }
-static READ64_HANDLER( nop_read64 ) { return space->unmap; }
-
-static WRITE8_HANDLER( nop_write8 ) { }
-static WRITE16_HANDLER( nop_write16 ) { }
-static WRITE32_HANDLER( nop_write32 ) { }
-static WRITE64_HANDLER( nop_write64 ) { }
-
-
-/*-------------------------------------------------
- watchpoint memory handlers
--------------------------------------------------*/
-
-static READ8_HANDLER( watchpoint_read8 )
-{
- address_space *spacerw = (address_space *)space;
- UINT8 *oldtable = spacerw->readlookup;
- UINT8 result;
-
- spacerw->cpu->debug()->memory_read_hook(*spacerw, offset, 0xff);
- spacerw->readlookup = space->read.table;
- result = read_byte_generic(spacerw, offset);
- spacerw->readlookup = oldtable;
- return result;
-}
-
-static READ16_HANDLER( watchpoint_read16 )
-{
- address_space *spacerw = (address_space *)space;
- UINT8 *oldtable = spacerw->readlookup;
- UINT16 result;
-
- spacerw->cpu->debug()->memory_read_hook(*spacerw, offset << 1, mem_mask);
- spacerw->readlookup = spacerw->read.table;
- result = read_word_generic(spacerw, offset << 1, mem_mask);
- spacerw->readlookup = oldtable;
- return result;
-}
-
-static READ32_HANDLER( watchpoint_read32 )
-{
- address_space *spacerw = (address_space *)space;
- UINT8 *oldtable = spacerw->readlookup;
- UINT32 result;
-
- spacerw->cpu->debug()->memory_read_hook(*spacerw, offset << 2, mem_mask);
- spacerw->readlookup = spacerw->read.table;
- result = read_dword_generic(spacerw, offset << 2, mem_mask);
- spacerw->readlookup = oldtable;
- return result;
-}
-
-static READ64_HANDLER( watchpoint_read64 )
-{
- address_space *spacerw = (address_space *)space;
- UINT8 *oldtable = spacerw->readlookup;
- UINT64 result;
-
- spacerw->cpu->debug()->memory_read_hook(*spacerw, offset << 3, mem_mask);
- spacerw->readlookup = spacerw->read.table;
- result = read_qword_generic(spacerw, offset << 3, mem_mask);
- spacerw->readlookup = oldtable;
- return result;
-}
-
-static WRITE8_HANDLER( watchpoint_write8 )
-{
- address_space *spacerw = (address_space *)space;
- UINT8 *oldtable = spacerw->writelookup;
-
- spacerw->cpu->debug()->memory_write_hook(*spacerw, offset, data, 0xff);
- spacerw->writelookup = spacerw->write.table;
- write_byte_generic(spacerw, offset, data);
- spacerw->writelookup = oldtable;
-}
-
-static WRITE16_HANDLER( watchpoint_write16 )
-{
- address_space *spacerw = (address_space *)space;
- UINT8 *oldtable = spacerw->writelookup;
-
- spacerw->cpu->debug()->memory_write_hook(*spacerw, offset << 1, data, mem_mask);
- spacerw->writelookup = spacerw->write.table;
- write_word_generic(spacerw, offset << 1, data, mem_mask);
- spacerw->writelookup = oldtable;
-}
-
-static WRITE32_HANDLER( watchpoint_write32 )
-{
- address_space *spacerw = (address_space *)space;
- UINT8 *oldtable = spacerw->writelookup;
-
- spacerw->cpu->debug()->memory_write_hook(*spacerw, offset << 2, data, mem_mask);
- spacerw->writelookup = spacerw->write.table;
- write_dword_generic(spacerw, offset << 2, data, mem_mask);
- spacerw->writelookup = oldtable;
-}
-
-static WRITE64_HANDLER( watchpoint_write64 )
-{
- address_space *spacerw = (address_space *)space;
- UINT8 *oldtable = spacerw->writelookup;
+ // mark the table dirty
+ m_subtable[subentry - SUBTABLE_BASE].m_checksum_valid = false;
- spacerw->cpu->debug()->memory_write_hook(*spacerw, offset << 3, data, mem_mask);
- spacerw->writelookup = spacerw->write.table;
- write_qword_generic(spacerw, offset << 3, data, mem_mask);
- spacerw->writelookup = oldtable;
+ // return the pointer to the subtable
+ return subtable_ptr(subentry);
}
-/*-------------------------------------------------
- get_static_handler - returns points to static
- memory handlers
--------------------------------------------------*/
+//-------------------------------------------------
+// subtable_close - stop access to a subtable
+//-------------------------------------------------
-static genf *get_static_handler(int handlerbits, int readorwrite, int which)
+void address_table::subtable_close(offs_t l1index)
{
- static const struct
- {
- UINT8 handlerbits;
- UINT8 handlernum;
- genf * read;
- genf * write;
- } static_handler_list[] =
- {
- { 8, STATIC_UNMAP, (genf *)unmap_read8, (genf *)unmap_write8 },
- { 8, STATIC_NOP, (genf *)nop_read8, (genf *)nop_write8 },
- { 8, STATIC_WATCHPOINT, (genf *)watchpoint_read8, (genf *)watchpoint_write8 },
-
- { 16, STATIC_UNMAP, (genf *)unmap_read16, (genf *)unmap_write16 },
- { 16, STATIC_NOP, (genf *)nop_read16, (genf *)nop_write16 },
- { 16, STATIC_WATCHPOINT, (genf *)watchpoint_read16, (genf *)watchpoint_write16 },
-
- { 32, STATIC_UNMAP, (genf *)unmap_read32, (genf *)unmap_write32 },
- { 32, STATIC_NOP, (genf *)nop_read32, (genf *)nop_write32 },
- { 32, STATIC_WATCHPOINT, (genf *)watchpoint_read32, (genf *)watchpoint_write32 },
-
- { 64, STATIC_UNMAP, (genf *)unmap_read64, (genf *)unmap_write64 },
- { 64, STATIC_NOP, (genf *)nop_read64, (genf *)nop_write64 },
- { 64, STATIC_WATCHPOINT, (genf *)watchpoint_read64, (genf *)watchpoint_write64 },
- };
- int tablenum;
-
- for (tablenum = 0; tablenum < sizeof(static_handler_list) / sizeof(static_handler_list[0]); tablenum++)
- if (static_handler_list[tablenum].handlerbits == handlerbits && static_handler_list[tablenum].handlernum == which)
- return readorwrite ? static_handler_list[tablenum].write : static_handler_list[tablenum].read;
-
- return NULL;
+ // defer any merging until we run out of tables
}
+//-------------------------------------------------
+// handler_name - return friendly string
+// description of a handler
+//-------------------------------------------------
-/***************************************************************************
- DEBUGGING
-***************************************************************************/
-
-/*-------------------------------------------------
- handler_to_string - return friendly string
- description of a handler
--------------------------------------------------*/
-
-static const char *handler_to_string(const address_space *space, const address_table *table, UINT8 entry)
+const char *address_table::handler_name(UINT8 entry) const
{
static const char *const strings[] =
{
@@ -3387,1204 +3261,1342 @@ static const char *handler_to_string(const address_space *space, const address_t
"rom", "nop", "unmapped", "watchpoint"
};
- /* banks have names */
+ // banks have names
if (entry >= STATIC_BANK1 && entry <= STATIC_BANKMAX)
- {
- bank_info *info;
- for (info = space->machine->memory_data->banklist; info != NULL; info = info->next)
- if (info->index == entry)
- return info->name;
- }
+ for (memory_bank *info = m_space.m_machine.memory_data->banklist.first(); info != NULL; info = info->next())
+ if (info->index() == entry)
+ return info->name();
- /* constant strings for lower entries */
- if (entry < STATIC_COUNT)
+ // constant strings for lower entries
+ if (entry < ARRAY_LENGTH(strings))
return strings[entry];
+ else if (handler(entry).name() != NULL)
+ return handler(entry).name();
else
- return (table->handlers[entry]->name != NULL) ? table->handlers[entry]->name : "???";
+ return "???";
}
-/*-------------------------------------------------
- dump_map - dump the contents of a single
- address space
--------------------------------------------------*/
+//-------------------------------------------------
+// address_table_read - constructor
+//-------------------------------------------------
-static void dump_map(FILE *file, const address_space *space, const address_table *table)
+address_table_read::address_table_read(address_space &space, bool large)
+ : address_table(space, large)
{
- offs_t byteaddress, bytestart, byteend;
-
- /* dump generic information */
- fprintf(file, " Address bits = %d\n", space->abits);
- fprintf(file, " Data bits = %d\n", space->dbits);
- fprintf(file, " L1 bits = %d\n", LEVEL1_BITS);
- fprintf(file, " L2 bits = %d\n", LEVEL2_BITS);
- fprintf(file, " Address mask = %X\n", space->bytemask);
- fprintf(file, "\n");
-
- /* iterate over addresses */
- for (byteaddress = 0; byteaddress <= space->bytemask; byteaddress = byteend + 1)
+ // allocate handlers for each entry, prepopulating the bankptrs for banks
+ for (int entrynum = 0; entrynum < ARRAY_LENGTH(m_handlers); entrynum++)
{
- UINT8 entry = table_derive_range(table, byteaddress, &bytestart, &byteend);
- fprintf(file, "%08X-%08X = %02X: %s [offset=%08X]\n",
- bytestart, byteend, entry, handler_to_string(space, table, entry), table->handlers[entry]->bytestart);
+ UINT8 **bankptr = (entrynum >= STATIC_BANK1 && entrynum <= STATIC_BANKMAX) ? &space.m_machine.memory_data->bank_ptr[entrynum] : NULL;
+ m_handlers[entrynum] = auto_alloc(&space.m_machine, handler_entry_read(space.data_width(), space.endianness(), bankptr));
}
-}
+ // we have to allocate different object types based on the data bus width
+ switch (space.data_width())
+ {
+ // 8-bit case
+ case 8:
+ m_handlers[STATIC_UNMAP]->set_delegate(read8_delegate_create(address_table_read, unmap_r<UINT8>, *this));
+ m_handlers[STATIC_NOP]->set_delegate(read8_delegate_create(address_table_read, nop_r<UINT8>, *this));
+ m_handlers[STATIC_WATCHPOINT]->set_delegate(read8_delegate_create(address_table_read, watchpoint_r<UINT8>, *this));
+ break;
-/*-------------------------------------------------
- mem_dump - internal memory dump
--------------------------------------------------*/
+ // 16-bit case
+ case 16:
+ m_handlers[STATIC_UNMAP]->set_delegate(read16_delegate_create(address_table_read, unmap_r<UINT16>, *this));
+ m_handlers[STATIC_NOP]->set_delegate(read16_delegate_create(address_table_read, nop_r<UINT16>, *this));
+ m_handlers[STATIC_WATCHPOINT]->set_delegate(read16_delegate_create(address_table_read, watchpoint_r<UINT16>, *this));
+ break;
-static void mem_dump(running_machine *machine)
-{
- FILE *file;
+ // 32-bit case
+ case 32:
+ m_handlers[STATIC_UNMAP]->set_delegate(read32_delegate_create(address_table_read, unmap_r<UINT32>, *this));
+ m_handlers[STATIC_NOP]->set_delegate(read32_delegate_create(address_table_read, nop_r<UINT32>, *this));
+ m_handlers[STATIC_WATCHPOINT]->set_delegate(read32_delegate_create(address_table_read, watchpoint_r<UINT32>, *this));
+ break;
- if (MEM_DUMP)
- {
- file = fopen("memdump.log", "w");
- if (file)
- {
- memory_dump(machine, file);
- fclose(file);
- }
+ // 64-bit case
+ case 64:
+ m_handlers[STATIC_UNMAP]->set_delegate(read64_delegate_create(address_table_read, unmap_r<UINT64>, *this));
+ m_handlers[STATIC_NOP]->set_delegate(read64_delegate_create(address_table_read, nop_r<UINT64>, *this));
+ m_handlers[STATIC_WATCHPOINT]->set_delegate(read64_delegate_create(address_table_read, watchpoint_r<UINT64>, *this));
+ break;
}
-}
-
+ // reset the byte masks on the special handlers to open up the full address space for proper reporting
+ m_handlers[STATIC_UNMAP]->configure(0, space.bytemask(), ~0);
+ m_handlers[STATIC_NOP]->configure(0, space.bytemask(), ~0);
+ m_handlers[STATIC_WATCHPOINT]->configure(0, space.bytemask(), ~0);
+}
-/***************************************************************************
- INPUT PORT READ HANDLERS
-***************************************************************************/
-/*-------------------------------------------------
- input port handlers
--------------------------------------------------*/
+//-------------------------------------------------
+// address_table_read - destructor
+//-------------------------------------------------
-static UINT8 input_port_read8(const input_port_config *port, offs_t offset)
+address_table_read::~address_table_read()
{
- return input_port_read_direct(port);
+ for (int handnum = 0; handnum < ARRAY_LENGTH(m_handlers); handnum++)
+ auto_free(&m_space.m_machine, m_handlers[handnum]);
}
-static UINT16 input_port_read16(const input_port_config *port, offs_t offset, UINT16 mem_mask)
-{
- return input_port_read_direct(port);
-}
-static UINT32 input_port_read32(const input_port_config *port, offs_t offset, UINT32 mem_mask)
-{
- return input_port_read_direct(port);
-}
+//-------------------------------------------------
+// handler - return the generic handler entry for
+// this index
+//-------------------------------------------------
-static UINT64 input_port_read64(const input_port_config *port, offs_t offset, UINT64 mem_mask)
+handler_entry &address_table_read::handler(UINT32 index) const
{
- return input_port_read_direct(port);
+ assert(index < ARRAY_LENGTH(m_handlers));
+ return *m_handlers[index];
}
+//-------------------------------------------------
+// address_table_write - constructor
+//-------------------------------------------------
-/*-------------------------------------------------
- output port handlers
--------------------------------------------------*/
-
-static void input_port_write8(const input_port_config *port, offs_t offset, UINT8 data)
+address_table_write::address_table_write(address_space &space, bool large)
+ : address_table(space, large)
{
- input_port_write_direct(port, data, 0xff);
-}
+ // allocate handlers for each entry, prepopulating the bankptrs for banks
+ for (int entrynum = 0; entrynum < ARRAY_LENGTH(m_handlers); entrynum++)
+ {
+ UINT8 **bankptr = (entrynum >= STATIC_BANK1 && entrynum <= STATIC_BANKMAX) ? &space.m_machine.memory_data->bank_ptr[entrynum] : NULL;
+ m_handlers[entrynum] = auto_alloc(&space.m_machine, handler_entry_write(space.data_width(), space.endianness(), bankptr));
+ }
-static void input_port_write16(const input_port_config *port, offs_t offset, UINT16 data, UINT16 mem_mask)
-{
- input_port_write_direct(port, data, mem_mask);
-}
+ // we have to allocate different object types based on the data bus width
+ switch (space.data_width())
+ {
+ // 8-bit case
+ case 8:
+ m_handlers[STATIC_UNMAP]->set_delegate(write8_delegate_create(address_table_write, unmap_w<UINT8>, *this));
+ m_handlers[STATIC_NOP]->set_delegate(write8_delegate_create(address_table_write, nop_w<UINT8>, *this));
+ m_handlers[STATIC_WATCHPOINT]->set_delegate(write8_delegate_create(address_table_write, watchpoint_w<UINT8>, *this));
+ break;
-static void input_port_write32(const input_port_config *port, offs_t offset, UINT32 data, UINT32 mem_mask)
-{
- input_port_write_direct(port, data, mem_mask);
-}
+ // 16-bit case
+ case 16:
+ m_handlers[STATIC_UNMAP]->set_delegate(write16_delegate_create(address_table_write, unmap_w<UINT16>, *this));
+ m_handlers[STATIC_NOP]->set_delegate(write16_delegate_create(address_table_write, nop_w<UINT16>, *this));
+ m_handlers[STATIC_WATCHPOINT]->set_delegate(write16_delegate_create(address_table_write, watchpoint_w<UINT16>, *this));
+ break;
-static void input_port_write64(const input_port_config *port, offs_t offset, UINT64 data, UINT64 mem_mask)
-{
- input_port_write_direct(port, data, mem_mask);
-}
+ // 32-bit case
+ case 32:
+ m_handlers[STATIC_UNMAP]->set_delegate(write32_delegate_create(address_table_write, unmap_w<UINT32>, *this));
+ m_handlers[STATIC_NOP]->set_delegate(write32_delegate_create(address_table_write, nop_w<UINT32>, *this));
+ m_handlers[STATIC_WATCHPOINT]->set_delegate(write32_delegate_create(address_table_write, watchpoint_w<UINT32>, *this));
+ break;
+ // 64-bit case
+ case 64:
+ m_handlers[STATIC_UNMAP]->set_delegate(write64_delegate_create(address_table_write, unmap_w<UINT64>, *this));
+ m_handlers[STATIC_NOP]->set_delegate(write64_delegate_create(address_table_write, nop_w<UINT64>, *this));
+ m_handlers[STATIC_WATCHPOINT]->set_delegate(write64_delegate_create(address_table_write, watchpoint_w<UINT64>, *this));
+ break;
+ }
+ // reset the byte masks on the special handlers to open up the full address space for proper reporting
+ m_handlers[STATIC_UNMAP]->configure(0, space.bytemask(), ~0);
+ m_handlers[STATIC_NOP]->configure(0, space.bytemask(), ~0);
+ m_handlers[STATIC_WATCHPOINT]->configure(0, space.bytemask(), ~0);
+}
-/***************************************************************************
- STUB HANDLERS THAT MAP TO BYTE READS
-***************************************************************************/
-/*-------------------------------------------------
- stub_read8_from_16 - return a 16-bit
- value combined from one or more byte accesses
--------------------------------------------------*/
+//-------------------------------------------------
+// address_table_write - destructor
+//-------------------------------------------------
-static READ16_HANDLER( stub_read8_from_16 )
+address_table_write::~address_table_write()
{
- const handler_data *handler = (const handler_data *)space;
- const UINT8 *subshift = handler->subshift;
- int subunits = handler->subunits;
- UINT16 result = 0;
-
- offset *= subunits;
- while (subunits-- != 0)
- {
- int shift = *subshift++;
- if ((UINT8)(mem_mask >> shift) != 0)
- result |= (*handler->subhandler.read.shandler8)((const address_space *)handler->subobject, offset) << shift;
- offset++;
- }
- return result;
+ for (int handnum = 0; handnum < ARRAY_LENGTH(m_handlers); handnum++)
+ auto_free(&m_space.m_machine, m_handlers[handnum]);
}
-/*-------------------------------------------------
- stub_read8_from_32 - return a 32-bit
- value combined from one or more byte accesses
--------------------------------------------------*/
+//-------------------------------------------------
+// handler - return the generic handler entry for
+// this index
+//-------------------------------------------------
-static READ32_HANDLER( stub_read8_from_32 )
+handler_entry &address_table_write::handler(UINT32 index) const
{
- const handler_data *handler = (const handler_data *)space;
- const UINT8 *subshift = handler->subshift;
- int subunits = handler->subunits;
- UINT32 result = 0;
-
- offset *= subunits;
- while (subunits-- != 0)
- {
- int shift = *subshift++;
- if ((UINT8)(mem_mask >> shift) != 0)
- result |= (*handler->subhandler.read.shandler8)((const address_space *)handler->subobject, offset) << shift;
- offset++;
- }
- return result;
+ assert(index < ARRAY_LENGTH(m_handlers));
+ return *m_handlers[index];
}
-/*-------------------------------------------------
- stub_read8_from_64 - return a 64-bit
- value combined from one or more byte accesses
--------------------------------------------------*/
-static READ64_HANDLER( stub_read8_from_64 )
-{
- const handler_data *handler = (const handler_data *)space;
- const UINT8 *subshift = handler->subshift;
- int subunits = handler->subunits;
- UINT64 result = 0;
+//**************************************************************************
+// DIRECT MEMORY RANGES
+//**************************************************************************
- offset *= subunits;
- while (subunits-- != 0)
- {
- int shift = *subshift++;
- if ((UINT8)(mem_mask >> shift) != 0)
- result |= (UINT64)(*handler->subhandler.read.shandler8)((const address_space *)handler->subobject, offset) << shift;
- offset++;
- }
- return result;
-}
+//-------------------------------------------------
+// direct_read_data - constructor
+//-------------------------------------------------
+direct_read_data::direct_read_data(address_space &space)
+ : m_space(space),
+ m_raw(NULL),
+ m_decrypted(NULL),
+ m_bytemask(space.bytemask()),
+ m_bytestart(1),
+ m_byteend(0),
+ m_entry(STATIC_UNMAP)
+{
+}
+
-/*-------------------------------------------------
- stub_read16_from_32 - return a 32-bit
- value combined from one or more word accesses
--------------------------------------------------*/
+//-------------------------------------------------
+// ~direct_read_data - destructor
+//-------------------------------------------------
-static READ32_HANDLER( stub_read16_from_32 )
+direct_read_data::~direct_read_data()
{
- const handler_data *handler = (const handler_data *)space;
- const UINT8 *subshift = handler->subshift;
- int subunits = handler->subunits;
- UINT32 result = 0;
-
- offset *= subunits;
- while (subunits-- != 0)
- {
- int shift = *subshift++;
- if ((UINT16)(mem_mask >> shift) != 0)
- result |= (*handler->subhandler.read.shandler16)((const address_space *)handler->subobject, offset, mem_mask >> shift) << shift;
- offset++;
- }
- return result;
}
-/*-------------------------------------------------
- stub_read16_from_64 - return a 64-bit
- value combined from one or more word accesses
--------------------------------------------------*/
+//-------------------------------------------------
+// set_direct_region - called by device cores to
+// update the opcode base for the given address
+//-------------------------------------------------
-static READ64_HANDLER( stub_read16_from_64 )
+bool direct_read_data::set_direct_region(offs_t &byteaddress)
{
- const handler_data *handler = (const handler_data *)space;
- const UINT8 *subshift = handler->subshift;
- int subunits = handler->subunits;
- UINT64 result = 0;
-
- offset *= subunits;
- while (subunits-- != 0)
+ // allow overrides
+ offs_t overrideaddress = byteaddress;
+ if (!m_directupdate.isnull())
{
- int shift = *subshift++;
- if ((UINT16)(mem_mask >> shift) != 0)
- result |= (UINT64)(*handler->subhandler.read.shandler16)((const address_space *)handler->subobject, offset, mem_mask >> shift) << shift;
- offset++;
- }
- return result;
-}
+ overrideaddress = m_directupdate(*this, overrideaddress);
+ if (overrideaddress == ~0)
+ return true;
+ byteaddress = overrideaddress;
+ }
-/*-------------------------------------------------
- stub_read32_from_64 - return a 64-bit
- value combined from one or more dword accesses
--------------------------------------------------*/
+ // remove the masked bits (we'll put them back later)
+ offs_t maskedbits = overrideaddress & ~m_bytemask;
-static READ64_HANDLER( stub_read32_from_64 )
-{
- const handler_data *handler = (const handler_data *)space;
- const UINT8 *subshift = handler->subshift;
- int subunits = handler->subunits;
- UINT64 result = 0;
+ // find or allocate a matching range
+ direct_range *range = find_range(overrideaddress, m_entry);
- offset *= subunits;
- while (subunits-- != 0)
+ // if we don't map to a bank, return FALSE
+ if (m_entry < STATIC_BANK1 || m_entry >= STATIC_RAM)
{
- int shift = *subshift++;
- if ((UINT32)(mem_mask >> shift) != 0)
- result |= (UINT64)(*handler->subhandler.read.shandler32)((const address_space *)handler->subobject, offset, mem_mask >> shift) << shift;
- offset++;
+ // ensure future updates to land here as well until we get back into a bank
+ m_byteend = 0;
+ m_bytestart = 1;
+ return false;
}
- return result;
-}
+ // if no decrypted opcodes, point to the same base
+ UINT8 *base = m_space.m_machine.memory_data->bank_ptr[m_entry];
+ UINT8 *based = m_space.m_machine.memory_data->bankd_ptr[m_entry];
+ if (based == NULL)
+ based = base;
+ // compute the adjusted base
+ const handler_entry_read &handler = m_space.read().handler_read(m_entry);
+ m_bytemask = handler.bytemask();
+ m_raw = base - (handler.bytestart() & m_bytemask);
+ m_decrypted = based - (handler.bytestart() & m_bytemask);
+ m_bytestart = maskedbits | range->m_bytestart;
+ m_byteend = maskedbits | range->m_byteend;
+ return true;
+}
-/***************************************************************************
- STUB HANDLERS THAT MAP TO BYTE WRITES
-***************************************************************************/
-/*-------------------------------------------------
- stub_write8_from_16 - convert a 16-bit
- write to one or more byte accesses
--------------------------------------------------*/
+//-------------------------------------------------
+// find_range - find a byte address in a range
+//-------------------------------------------------
-static WRITE16_HANDLER( stub_write8_from_16 )
+direct_read_data::direct_range *direct_read_data::find_range(offs_t byteaddress, UINT8 &entry)
{
- const handler_data *handler = (const handler_data *)space;
- const UINT8 *subshift = handler->subshift;
- int subunits = handler->subunits;
+ // determine which entry
+ byteaddress &= m_space.m_bytemask;
+ entry = m_space.read().lookup_live(byteaddress);
- offset *= subunits;
- while (subunits-- != 0)
- {
- int shift = *subshift++;
- if ((UINT8)(mem_mask >> shift) != 0)
- (*handler->subhandler.write.shandler8)((const address_space *)handler->subobject, offset, data >> shift);
- offset++;
- }
+ // scan our table
+ for (direct_range *range = m_rangelist[entry].first(); range != NULL; range = range->next())
+ if (byteaddress >= range->m_bytestart && byteaddress <= range->m_byteend)
+ return range;
+
+ // didn't find out; allocate a new one
+ direct_range *range = m_freerangelist.first();
+ if (range != NULL)
+ m_freerangelist.detach(*range);
+ else
+ range = auto_alloc(&m_space.m_machine, direct_range);
+
+ // fill in the range
+ m_space.read().derive_range(byteaddress, range->m_bytestart, range->m_byteend);
+ m_rangelist[entry].prepend(*range);
+
+ return range;
}
-/*-------------------------------------------------
- stub_write8_from_32 - convert a 32-bit
- write to one or more byte accesses
--------------------------------------------------*/
+//-------------------------------------------------
+// remove_intersecting_ranges - remove all cached
+// ranges that intersect the given address range
+//-------------------------------------------------
-static WRITE32_HANDLER( stub_write8_from_32 )
+void direct_read_data::remove_intersecting_ranges(offs_t bytestart, offs_t byteend)
{
- const handler_data *handler = (const handler_data *)space;
- const UINT8 *subshift = handler->subshift;
- int subunits = handler->subunits;
-
- offset *= subunits;
- while (subunits-- != 0)
+ // loop over all entries
+ for (int entry = 0; entry < ARRAY_LENGTH(m_rangelist); entry++)
{
- int shift = *subshift++;
- if ((UINT8)(mem_mask >> shift) != 0)
- (*handler->subhandler.write.shandler8)((const address_space *)handler->subobject, offset, data >> shift);
- offset++;
+ // loop over all ranges in this entry's list
+ direct_range *nextrange;
+ for (direct_range *range = m_rangelist[entry].first(); range != NULL; range = nextrange)
+ {
+ nextrange = range->next();
+
+ // if we intersect, remove and add to the free range list
+ if (bytestart <= range->m_byteend && byteend >= range->m_bytestart)
+ {
+ m_rangelist[entry].detach(*range);
+ m_freerangelist.prepend(*range);
+ }
+ }
}
}
-/*-------------------------------------------------
- stub_write8_from_64 - convert a 64-bit
- write to one or more byte accesses
--------------------------------------------------*/
+//-------------------------------------------------
+// set_direct_update - set a custom direct range
+// update callback
+//-------------------------------------------------
-static WRITE64_HANDLER( stub_write8_from_64 )
+direct_update_delegate direct_read_data::set_direct_update(direct_update_delegate function)
{
- const handler_data *handler = (const handler_data *)space;
- const UINT8 *subshift = handler->subshift;
- int subunits = handler->subunits;
-
- offset *= subunits;
- while (subunits-- != 0)
- {
- int shift = *subshift++;
- if ((UINT8)(mem_mask >> shift) != 0)
- (*handler->subhandler.write.shandler8)((const address_space *)handler->subobject, offset, data >> shift);
- offset++;
- }
+ direct_update_delegate old = m_directupdate;
+ m_directupdate = function;
+ return old;
}
-/*-------------------------------------------------
- stub_write16_from_32 - convert a 32-bit
- write to one or more word accesses
--------------------------------------------------*/
+//-------------------------------------------------
+// explicit_configure - explicitly configure
+// the start/end/mask and the pointers from
+// within a custom callback
+//-------------------------------------------------
-static WRITE32_HANDLER( stub_write16_from_32 )
+void direct_read_data::explicit_configure(offs_t bytestart, offs_t byteend, offs_t bytemask, void *raw, void *decrypted)
{
- const handler_data *handler = (const handler_data *)space;
- const UINT8 *subshift = handler->subshift;
- int subunits = handler->subunits;
-
- offset *= subunits;
- while (subunits-- != 0)
- {
- int shift = *subshift++;
- if ((UINT16)(mem_mask >> shift) != 0)
- (*handler->subhandler.write.shandler16)((const address_space *)handler->subobject, offset, data >> shift, mem_mask >> shift);
- offset++;
- }
+ m_bytestart = bytestart;
+ m_byteend = byteend;
+ m_bytemask = bytemask;
+ m_raw = reinterpret_cast<UINT8 *>(raw);
+ m_decrypted = reinterpret_cast<UINT8 *>((decrypted == NULL) ? raw : decrypted);
+ m_raw -= bytestart & bytemask;
+ m_decrypted -= bytestart & bytemask;
}
-/*-------------------------------------------------
- stub_write16_from_64 - convert a 64-bit
- write to one or more word accesses
--------------------------------------------------*/
-static WRITE64_HANDLER( stub_write16_from_64 )
+//**************************************************************************
+// MEMORY BLOCK
+//**************************************************************************
+
+//-------------------------------------------------
+// memory_block - constructor
+//-------------------------------------------------
+
+memory_block::memory_block(address_space &space, offs_t bytestart, offs_t byteend, void *memory)
+ : m_next(NULL),
+ m_machine(space.m_machine),
+ m_space(space),
+ m_isallocated(memory == NULL),
+ m_bytestart(bytestart),
+ m_byteend(byteend),
+ m_data((memory != NULL) ? reinterpret_cast<UINT8 *>(memory) : auto_alloc_array_clear(&space.m_machine, UINT8, byteend + 1 - bytestart))
{
- const handler_data *handler = (const handler_data *)space;
- const UINT8 *subshift = handler->subshift;
- int subunits = handler->subunits;
+ VPRINTF(("block_allocate('%s',%s,%08X,%08X,%p)\n", space.device().tag(), space.name(), bytestart, byteend, memory));
+
+ // register for saving, but only if we're not part of a memory region
+ const region_info *region;
+ for (region = space.m_machine.m_regionlist.first(); region != NULL; region = region->next())
+ if (m_data >= region->base() && (m_data + (byteend - bytestart + 1)) < region->end())
+ {
+ VPRINTF(("skipping save of this memory block as it is covered by a memory region\n"));
+ break;
+ }
- offset *= subunits;
- while (subunits-- != 0)
+ // if we didn't find a match, register
+ if (region == NULL)
{
- int shift = *subshift++;
- if ((UINT16)(mem_mask >> shift) != 0)
- (*handler->subhandler.write.shandler16)((const address_space *)handler->subobject, offset, data >> shift, mem_mask >> shift);
- offset++;
+ int bytes_per_element = space.data_width() / 8;
+ astring name;
+ name.printf("%08x-%08x", bytestart, byteend);
+ state_save_register_memory(&space.m_machine, "memory", space.device().tag(), space.spacenum(), name, m_data, bytes_per_element, (UINT32)(byteend + 1 - bytestart) / bytes_per_element, __FILE__, __LINE__);
}
}
-/*-------------------------------------------------
- stub_write32_from_64 - convert a 64-bit
- write to one or more word accesses
--------------------------------------------------*/
+//-------------------------------------------------
+// memory_block - destructor
+//-------------------------------------------------
-static WRITE64_HANDLER( stub_write32_from_64 )
+memory_block::~memory_block()
{
- const handler_data *handler = (const handler_data *)space;
- const UINT8 *subshift = handler->subshift;
- int subunits = handler->subunits;
-
- offset *= subunits;
- while (subunits-- != 0)
- {
- int shift = *subshift++;
- if ((UINT32)(mem_mask >> shift) != 0)
- (*handler->subhandler.write.shandler32)((const address_space *)handler->subobject, offset, data >> shift, mem_mask >> shift);
- offset++;
- }
+ if (m_isallocated)
+ auto_free(&m_machine, m_data);
}
-/***************************************************************************
- STUB ACCESSORS
-***************************************************************************/
+//**************************************************************************
+// MEMORY BANK
+//**************************************************************************
-/*-------------------------------------------------
- get_stub_handler - return the appropriate
- stub handler
--------------------------------------------------*/
+//-------------------------------------------------
+// memory_bank - constructor
+//-------------------------------------------------
-static memory_handler get_stub_handler(read_or_write readorwrite, int spacedbits, int handlerdbits)
+memory_bank::memory_bank(address_space &space, int index, offs_t bytestart, offs_t byteend, const char *tag)
+ : m_next(NULL),
+ m_machine(space.m_machine),
+ m_baseptr(&space.m_machine.memory_data->bank_ptr[index]),
+ m_basedptr(&space.m_machine.memory_data->bankd_ptr[index]),
+ m_index(index),
+ m_anonymous(tag == NULL),
+ m_bytestart(bytestart),
+ m_byteend(byteend),
+ m_curentry(BANK_ENTRY_UNSPECIFIED),
+ m_entry(NULL),
+ m_entry_count(0)
{
- memory_handler result = { 0 };
-
- /* read stubs */
- if (readorwrite == ROW_READ)
+ // generate an internal tag if we don't have one
+ if (tag == NULL)
{
- /* 16-bit read stubs */
- if (spacedbits == 16)
- {
- if (handlerdbits == 8)
- result.read.shandler16 = stub_read8_from_16;
- }
-
- /* 32-bit read stubs */
- else if (spacedbits == 32)
- {
- if (handlerdbits == 8)
- result.read.shandler32 = stub_read8_from_32;
- else if (handlerdbits == 16)
- result.read.shandler32 = stub_read16_from_32;
- }
-
- /* 64-bit read stubs */
- else if (spacedbits == 64)
- {
- if (handlerdbits == 8)
- result.read.shandler64 = stub_read8_from_64;
- else if (handlerdbits == 16)
- result.read.shandler64 = stub_read16_from_64;
- else if (handlerdbits == 32)
- result.read.shandler64 = stub_read32_from_64;
- }
+ m_tag.printf("~%d~", index);
+ m_name.printf("Internal bank #%d", index);
}
-
- /* write stubs */
- else if (readorwrite == ROW_WRITE)
+ else
{
- /* 16-bit write stubs */
- if (spacedbits == 16)
- {
- if (handlerdbits == 8)
- result.write.shandler16 = stub_write8_from_16;
- }
-
- /* 32-bit write stubs */
- else if (spacedbits == 32)
- {
- if (handlerdbits == 8)
- result.write.shandler32 = stub_write8_from_32;
- else if (handlerdbits == 16)
- result.write.shandler32 = stub_write16_from_32;
- }
-
- /* 64-bit write stubs */
- else if (spacedbits == 64)
- {
- if (handlerdbits == 8)
- result.write.shandler64 = stub_write8_from_64;
- else if (handlerdbits == 16)
- result.write.shandler64 = stub_write16_from_64;
- else if (handlerdbits == 32)
- result.write.shandler64 = stub_write32_from_64;
- }
+ m_tag.cpy(tag);
+ m_name.printf("Bank '%s'", tag);
}
- assert(result.read.generic != NULL);
- return result;
+ if (!m_anonymous && state_save_registration_allowed(&space.m_machine))
+ state_save_register_item(&space.m_machine, "memory", m_tag, 0, m_curentry);
}
+//-------------------------------------------------
+// memory_bank - destructor
+//-------------------------------------------------
-/***************************************************************************
- 8-BIT READ HANDLERS
-***************************************************************************/
-
-UINT8 memory_read_byte_8le(const address_space *space, offs_t address)
+memory_bank::~memory_bank()
{
- return read_byte_generic(space, address);
+ auto_free(&m_machine, m_entry);
}
-UINT8 memory_read_byte_8be(const address_space *space, offs_t address)
-{
- return read_byte_generic(space, address);
-}
-UINT16 memory_read_word_8le(const address_space *space, offs_t address)
-{
- UINT16 result = memory_read_byte_8le(space, address + 0) << 0;
- return result | (memory_read_byte_8le(space, address + 1) << 8);
-}
+//-------------------------------------------------
+// references_space - walk the list of references
+// to find a match against the provided space
+// and read/write
+//-------------------------------------------------
-UINT16 memory_read_word_masked_8le(const address_space *space, offs_t address, UINT16 mask)
+bool memory_bank::references_space(address_space &space, read_or_write readorwrite) const
{
- UINT16 result = 0;
- if (mask & 0x00ff) result |= memory_read_byte_8le(space, address + 0) << 0;
- if (mask & 0xff00) result |= memory_read_byte_8le(space, address + 1) << 8;
- return result;
+ for (bank_reference *ref = m_reflist.first(); ref != NULL; ref = ref->next())
+ if (ref->matches(space, readorwrite))
+ return true;
+ return false;
}
-UINT16 memory_read_word_8be(const address_space *space, offs_t address)
-{
- UINT16 result = memory_read_byte_8be(space, address + 0) << 8;
- return result | (memory_read_byte_8be(space, address + 1) << 0);
-}
-UINT16 memory_read_word_masked_8be(const address_space *space, offs_t address, UINT16 mask)
-{
- UINT16 result = 0;
- if (mask & 0xff00) result |= memory_read_byte_8be(space, address + 0) << 8;
- if (mask & 0x00ff) result |= memory_read_byte_8be(space, address + 1) << 0;
- return result;
-}
+//-------------------------------------------------
+// add_reference - add a new reference to the
+// given space
+//-------------------------------------------------
-UINT32 memory_read_dword_8le(const address_space *space, offs_t address)
+void memory_bank::add_reference(address_space &space, read_or_write readorwrite)
{
- UINT32 result = memory_read_word_8le(space, address + 0) << 0;
- return result | (memory_read_word_8le(space, address + 2) << 16);
+ // if we already have a reference, skip it
+ if (references_space(space, readorwrite))
+ return;
+ m_reflist.append(*auto_alloc(&space.m_machine, bank_reference(space, readorwrite)));
}
-UINT32 memory_read_dword_masked_8le(const address_space *space, offs_t address, UINT32 mask)
-{
- UINT32 result = 0;
- if (mask & 0x0000ffff) result |= memory_read_word_masked_8le(space, address + 0, mask >> 0) << 0;
- if (mask & 0xffff0000) result |= memory_read_word_masked_8le(space, address + 2, mask >> 16) << 16;
- return result;
-}
-UINT32 memory_read_dword_8be(const address_space *space, offs_t address)
-{
- UINT32 result = memory_read_word_8be(space, address + 0) << 16;
- return result | (memory_read_word_8be(space, address + 2) << 0);
-}
+//-------------------------------------------------
+// invalidate_references - force updates on all
+// referencing address spaces
+//-------------------------------------------------
-UINT32 memory_read_dword_masked_8be(const address_space *space, offs_t address, UINT32 mask)
+void memory_bank::invalidate_references()
{
- UINT32 result = 0;
- if (mask & 0xffff0000) result |= memory_read_word_masked_8be(space, address + 0, mask >> 16) << 16;
- if (mask & 0x0000ffff) result |= memory_read_word_masked_8be(space, address + 2, mask >> 0) << 0;
- return result;
+ // invalidate all the direct references to any referenced address spaces
+ for (bank_reference *ref = m_reflist.first(); ref != NULL; ref = ref->next())
+ ref->space().direct().force_update();
}
-UINT64 memory_read_qword_8le(const address_space *space, offs_t address)
-{
- UINT64 result = (UINT64)memory_read_dword_8le(space, address + 0) << 0;
- return result | ((UINT64)memory_read_dword_8le(space, address + 4) << 32);
-}
-UINT64 memory_read_qword_masked_8le(const address_space *space, offs_t address, UINT64 mask)
-{
- UINT64 result = 0;
- if (mask & U64(0x00000000ffffffff)) result |= (UINT64)memory_read_dword_masked_8le(space, address + 0, mask >> 0) << 0;
- if (mask & U64(0xffffffff00000000)) result |= (UINT64)memory_read_dword_masked_8le(space, address + 4, mask >> 32) << 32;
- return result;
-}
+//-------------------------------------------------
+// set_base - set the bank base explicitly
+//-------------------------------------------------
-UINT64 memory_read_qword_8be(const address_space *space, offs_t address)
+void memory_bank::set_base(void *base)
{
- UINT64 result = (UINT64)memory_read_dword_8be(space, address + 0) << 32;
- return result | ((UINT64)memory_read_dword_8be(space, address + 4) << 0);
-}
+ // NULL is not an option
+ if (base == NULL)
+ throw emu_fatalerror("memory_bank::set_base called NULL base");
-UINT64 memory_read_qword_masked_8be(const address_space *space, offs_t address, UINT64 mask)
-{
- UINT64 result = 0;
- if (mask & U64(0xffffffff00000000)) result |= (UINT64)memory_read_dword_masked_8be(space, address + 0, mask >> 32) << 32;
- if (mask & U64(0x00000000ffffffff)) result |= (UINT64)memory_read_dword_masked_8be(space, address + 4, mask >> 0) << 0;
- return result;
+ // set the base and invalidate any referencing spaces
+ *m_baseptr = reinterpret_cast<UINT8 *>(base);
+ invalidate_references();
}
+//-------------------------------------------------
+// set_base_decrypted - set the decrypted base
+// explicitly
+//-------------------------------------------------
-/***************************************************************************
- 8-BIT WRITE HANDLERS
-***************************************************************************/
-
-void memory_write_byte_8le(const address_space *space, offs_t address, UINT8 data)
+void memory_bank::set_base_decrypted(void *base)
{
- write_byte_generic(space, address, data);
-}
+ // NULL is not an option
+ if (base == NULL)
+ throw emu_fatalerror("memory_bank::set_base called NULL base");
-void memory_write_byte_8be(const address_space *space, offs_t address, UINT8 data)
-{
- write_byte_generic(space, address, data);
+ // set the base and invalidate any referencing spaces
+ *m_basedptr = reinterpret_cast<UINT8 *>(base);
+ invalidate_references();
}
-void memory_write_word_8le(const address_space *space, offs_t address, UINT16 data)
-{
- memory_write_byte_8le(space, address + 0, data >> 0);
- memory_write_byte_8le(space, address + 1, data >> 8);
-}
-void memory_write_word_masked_8le(const address_space *space, offs_t address, UINT16 data, UINT16 mask)
-{
- if (mask & 0x00ff) memory_write_byte_8le(space, address + 0, data >> 0);
- if (mask & 0xff00) memory_write_byte_8le(space, address + 1, data >> 8);
-}
+//-------------------------------------------------
+// set_entry - set the base to a pre-configured
+// entry
+//-------------------------------------------------
-void memory_write_word_8be(const address_space *space, offs_t address, UINT16 data)
+void memory_bank::set_entry(int entrynum)
{
- memory_write_byte_8be(space, address + 0, data >> 8);
- memory_write_byte_8be(space, address + 1, data >> 0);
-}
+ // validate
+ if (m_anonymous)
+ throw emu_fatalerror("memory_bank::set_entry called for anonymous bank");
+ if (entrynum < 0 || entrynum >= m_entry_count)
+ throw emu_fatalerror("memory_bank::set_entry called with out-of-range entry %d", entrynum);
+ if (m_entry[entrynum].m_raw == NULL)
+ throw emu_fatalerror("memory_bank::set_entry called for bank '%s' with invalid bank entry %d", m_tag.cstr(), entrynum);
-void memory_write_word_masked_8be(const address_space *space, offs_t address, UINT16 data, UINT16 mask)
-{
- if (mask & 0xff00) memory_write_byte_8be(space, address + 0, data >> 8);
- if (mask & 0x00ff) memory_write_byte_8be(space, address + 1, data >> 0);
-}
+ // set both raw and decrypted values
+ m_curentry = entrynum;
+ *m_baseptr = m_entry[entrynum].m_raw;
+ *m_basedptr = m_entry[entrynum].m_decrypted;
-void memory_write_dword_8le(const address_space *space, offs_t address, UINT32 data)
-{
- memory_write_word_8le(space, address + 0, data >> 0);
- memory_write_word_8le(space, address + 2, data >> 16);
+ // invalidate referencing spaces
+ invalidate_references();
}
-void memory_write_dword_masked_8le(const address_space *space, offs_t address, UINT32 data, UINT32 mask)
-{
- if (mask & 0x0000ffff) memory_write_word_masked_8le(space, address + 0, data >> 0, mask >> 0);
- if (mask & 0xffff0000) memory_write_word_masked_8le(space, address + 2, data >> 16, mask >> 16);
-}
-void memory_write_dword_8be(const address_space *space, offs_t address, UINT32 data)
-{
- memory_write_word_8be(space, address + 0, data >> 16);
- memory_write_word_8be(space, address + 2, data >> 0);
-}
+//-------------------------------------------------
+// expand_entries - expand the allocated array
+// of entries
+//-------------------------------------------------
-void memory_write_dword_masked_8be(const address_space *space, offs_t address, UINT32 data, UINT32 mask)
+void memory_bank::expand_entries(int entrynum)
{
- if (mask & 0xffff0000) memory_write_word_masked_8be(space, address + 0, data >> 16, mask >> 16);
- if (mask & 0x0000ffff) memory_write_word_masked_8be(space, address + 2, data >> 0, mask >> 0);
-}
+ int newcount = entrynum + 1;
+
+ // allocate a new array and copy from the old one; zero out the new entries
+ bank_entry *newentry = auto_alloc_array(&m_machine, bank_entry, newcount);
+ memcpy(newentry, m_entry, sizeof(m_entry[0]) * m_entry_count);
+ memset(&newentry[m_entry_count], 0, (newcount - m_entry_count) * sizeof(m_entry[0]));
-void memory_write_qword_8le(const address_space *space, offs_t address, UINT64 data)
-{
- memory_write_dword_8le(space, address + 0, data >> 0);
- memory_write_dword_8le(space, address + 4, data >> 32);
+ // free the old array and set the updated values
+ auto_free(&m_machine, m_entry);
+ m_entry = newentry;
+ m_entry_count = newcount;
}
-void memory_write_qword_masked_8le(const address_space *space, offs_t address, UINT64 data, UINT64 mask)
-{
- if (mask & U64(0x00000000ffffffff)) memory_write_dword_masked_8le(space, address + 0, data >> 0, mask >> 0);
- if (mask & U64(0xffffffff00000000)) memory_write_dword_masked_8le(space, address + 4, data >> 32, mask >> 32);
-}
-void memory_write_qword_8be(const address_space *space, offs_t address, UINT64 data)
-{
- memory_write_dword_8be(space, address + 0, data >> 32);
- memory_write_dword_8be(space, address + 4, data >> 0);
-}
+//-------------------------------------------------
+// configure - configure an entry
+//-------------------------------------------------
-void memory_write_qword_masked_8be(const address_space *space, offs_t address, UINT64 data, UINT64 mask)
+void memory_bank::configure(int entrynum, void *base)
{
- if (mask & U64(0xffffffff00000000)) memory_write_dword_masked_8be(space, address + 0, data >> 32, mask >> 32);
- if (mask & U64(0x00000000ffffffff)) memory_write_dword_masked_8be(space, address + 4, data >> 0, mask >> 0);
-}
-
+ // must be positive
+ if (entrynum < 0)
+ throw emu_fatalerror("memory_bank::configure called with out-of-range entry %d", entrynum);
+ // if we haven't allocated this many entries yet, expand our array
+ if (entrynum >= m_entry_count)
+ expand_entries(entrynum);
-/***************************************************************************
- 16-BIT READ HANDLERS
-***************************************************************************/
+ // set the entry
+ m_entry[entrynum].m_raw = reinterpret_cast<UINT8 *>(base);
-UINT8 memory_read_byte_16le(const address_space *space, offs_t address)
-{
- UINT32 shift = (address & 1) * 8;
- return read_word_generic(space, address, 0xff << shift) >> shift;
+ // if the bank base is not configured, and we're the first entry, set us up
+ if (*m_baseptr == NULL && entrynum == 0)
+ *m_baseptr = m_entry[entrynum].m_raw;
}
-UINT8 memory_read_byte_16be(const address_space *space, offs_t address)
-{
- UINT32 shift = (~address & 1) * 8;
- return read_word_generic(space, address, 0xff << shift) >> shift;
-}
-UINT16 memory_read_word_16le(const address_space *space, offs_t address)
-{
- return read_word_generic(space, address, 0xffff);
-}
+//-------------------------------------------------
+// configure_decrypted - configure a decrypted
+// entry
+//-------------------------------------------------
-UINT16 memory_read_word_masked_16le(const address_space *space, offs_t address, UINT16 mask)
+void memory_bank::configure_decrypted(int entrynum, void *base)
{
- return read_word_generic(space, address, mask);
-}
+ // must be positive
+ if (entrynum < 0)
+ throw emu_fatalerror("memory_bank::configure called with out-of-range entry %d", entrynum);
-UINT16 memory_read_word_16be(const address_space *space, offs_t address)
-{
- return read_word_generic(space, address, 0xffff);
-}
+ // if we haven't allocated this many entries yet, expand our array
+ if (entrynum >= m_entry_count)
+ expand_entries(entrynum);
-UINT16 memory_read_word_masked_16be(const address_space *space, offs_t address, UINT16 mask)
-{
- return read_word_generic(space, address, mask);
-}
+ // set the entry
+ m_entry[entrynum].m_decrypted = reinterpret_cast<UINT8 *>(base);
-UINT32 memory_read_dword_16le(const address_space *space, offs_t address)
-{
- UINT32 result = memory_read_word_16le(space, address + 0) << 0;
- return result | (memory_read_word_16le(space, address + 2) << 16);
+ // if the bank base is not configured, and we're the first entry, set us up
+ if (*m_basedptr == NULL && entrynum == 0)
+ *m_basedptr = m_entry[entrynum].m_decrypted;
}
-UINT32 memory_read_dword_masked_16le(const address_space *space, offs_t address, UINT32 mask)
-{
- UINT32 result = 0;
- if (mask & 0x0000ffff) result |= memory_read_word_masked_16le(space, address + 0, mask >> 0) << 0;
- if (mask & 0xffff0000) result |= memory_read_word_masked_16le(space, address + 2, mask >> 16) << 16;
- return result;
-}
-UINT32 memory_read_dword_16be(const address_space *space, offs_t address)
-{
- UINT32 result = memory_read_word_16be(space, address + 0) << 16;
- return result | (memory_read_word_16be(space, address + 2) << 0);
-}
-UINT32 memory_read_dword_masked_16be(const address_space *space, offs_t address, UINT32 mask)
-{
- UINT32 result = 0;
- if (mask & 0xffff0000) result |= memory_read_word_masked_16be(space, address + 0, mask >> 16) << 16;
- if (mask & 0x0000ffff) result |= memory_read_word_masked_16be(space, address + 2, mask >> 0) << 0;
- return result;
-}
+//**************************************************************************
+// HANDLER ENTRY
+//**************************************************************************
-UINT64 memory_read_qword_16le(const address_space *space, offs_t address)
-{
- UINT64 result = (UINT64)memory_read_dword_16le(space, address + 0) << 0;
- return result | ((UINT64)memory_read_dword_16le(space, address + 4) << 32);
-}
+//-------------------------------------------------
+// handler_entry - constructor
+//-------------------------------------------------
-UINT64 memory_read_qword_masked_16le(const address_space *space, offs_t address, UINT64 mask)
+handler_entry::handler_entry(UINT8 width, endianness_t endianness, UINT8 **rambaseptr)
+ : m_populated(false),
+ m_datawidth(width),
+ m_endianness(endianness),
+ m_bytestart(0),
+ m_byteend(0),
+ m_bytemask(~0),
+ m_rambaseptr(rambaseptr),
+ m_subunits(0)
{
- UINT64 result = 0;
- if (mask & U64(0x00000000ffffffff)) result |= (UINT64)memory_read_dword_masked_16le(space, address + 0, mask >> 0) << 0;
- if (mask & U64(0xffffffff00000000)) result |= (UINT64)memory_read_dword_masked_16le(space, address + 4, mask >> 32) << 32;
- return result;
}
-UINT64 memory_read_qword_16be(const address_space *space, offs_t address)
+
+//-------------------------------------------------
+// ~handler_entry - destructor
+//-------------------------------------------------
+
+handler_entry::~handler_entry()
{
- UINT64 result = (UINT64)memory_read_dword_16be(space, address + 0) << 32;
- return result | ((UINT64)memory_read_dword_16be(space, address + 4) << 0);
}
-UINT64 memory_read_qword_masked_16be(const address_space *space, offs_t address, UINT64 mask)
+
+//-------------------------------------------------
+// configure_subunits - configure the subunits
+// and subshift array to represent the provided
+// mask
+//-------------------------------------------------
+
+void handler_entry::configure_subunits(UINT64 handlermask, int handlerbits)
{
- UINT64 result = 0;
- if (mask & U64(0xffffffff00000000)) result |= (UINT64)memory_read_dword_masked_16be(space, address + 0, mask >> 32) << 32;
- if (mask & U64(0x00000000ffffffff)) result |= (UINT64)memory_read_dword_masked_16be(space, address + 4, mask >> 0) << 0;
- return result;
+ UINT64 unitmask = ((UINT64)1 << handlerbits) - 1;
+ assert(handlermask != 0);
+
+ // compute the maximum possible subunits
+ int maxunits = m_datawidth / handlerbits;
+ assert(maxunits > 1);
+ assert(maxunits < ARRAY_LENGTH(m_subshift));
+
+ // walk the handlermask to find out how many we have
+ m_subunits = 0;
+ for (int unitnum = 0; unitnum < maxunits; unitnum++)
+ {
+ UINT64 scanmask = unitmask << (unitnum * handlerbits);
+ assert((handlermask & scanmask) == 0 || (handlermask & scanmask) == scanmask);
+ if ((handlermask & scanmask) != 0)
+ m_subunits++;
+ }
+
+ // then fill in the shifts based on the endianness
+ if (m_endianness == ENDIANNESS_LITTLE)
+ {
+ UINT8 *unitshift = &m_subshift[0];
+ for (int unitnum = 0; unitnum < maxunits; unitnum++)
+ if ((handlermask & (unitmask << (unitnum * handlerbits))) != 0)
+ *unitshift++ = unitnum * handlerbits;
+ }
+ else
+ {
+ UINT8 *unitshift = &m_subshift[m_subunits];
+ for (int unitnum = 0; unitnum < maxunits; unitnum++)
+ if ((handlermask & (unitmask << (unitnum * handlerbits))) != 0)
+ *--unitshift = unitnum * handlerbits;
+ }
}
-/***************************************************************************
- 16-BIT WRITE HANDLERS
-***************************************************************************/
+//**************************************************************************
+// HANDLER ENTRY READ
+//**************************************************************************
-void memory_write_byte_16le(const address_space *space, offs_t address, UINT8 data)
-{
- UINT32 shift = (address & 1) * 8;
- write_word_generic(space, address, data << shift, 0xff << shift);
-}
+//-------------------------------------------------
+// name - return the handler name, from the
+// appropriately-sized delegate
+//-------------------------------------------------
-void memory_write_byte_16be(const address_space *space, offs_t address, UINT8 data)
+const char *handler_entry_read::name() const
{
- UINT32 shift = (~address & 1) * 8;
- write_word_generic(space, address, data << shift, 0xff << shift);
+ switch (m_datawidth)
+ {
+ case 8: return m_read8.name();
+ case 16: return m_read16.name();
+ case 32: return m_read32.name();
+ case 64: return m_read64.name();
+ }
+ return NULL;
}
-void memory_write_word_16le(const address_space *space, offs_t address, UINT16 data)
-{
- write_word_generic(space, address, data, 0xffff);
-}
-void memory_write_word_masked_16le(const address_space *space, offs_t address, UINT16 data, UINT16 mask)
-{
- write_word_generic(space, address, data, mask);
-}
+//-------------------------------------------------
+// set_delegate - set an 8-bit delegate, and
+// configure a stub if necessary
+//-------------------------------------------------
-void memory_write_word_16be(const address_space *space, offs_t address, UINT16 data)
+void handler_entry_read::set_delegate(read8_delegate delegate, UINT64 mask)
{
- write_word_generic(space, address, data, 0xffff);
-}
+ // error if no object
+ if (!delegate.has_object())
+ throw emu_fatalerror("Attempted to install delegate '%s' without a bound object", delegate.name());
-void memory_write_word_masked_16be(const address_space *space, offs_t address, UINT16 data, UINT16 mask)
-{
- write_word_generic(space, address, data, mask);
+ // make sure this is a valid size
+ assert(m_datawidth >= 8);
+ m_read8 = delegate;
+
+ // if mismatched bus width, configure a stub
+ if (m_datawidth != 8)
+ {
+ configure_subunits(mask, 8);
+ if (m_datawidth == 16)
+ set_delegate(read16_delegate(read16_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_16_from_8>(delegate.name()), *this));
+ else if (m_datawidth == 32)
+ set_delegate(read32_delegate(read32_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_32_from_8>(delegate.name()), *this));
+ else if (m_datawidth == 64)
+ set_delegate(read64_delegate(read64_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_64_from_8>(delegate.name()), *this));
+ }
}
-void memory_write_dword_16le(const address_space *space, offs_t address, UINT32 data)
-{
- memory_write_word_16le(space, address + 0, data >> 0);
- memory_write_word_16le(space, address + 2, data >> 16);
-}
-void memory_write_dword_masked_16le(const address_space *space, offs_t address, UINT32 data, UINT32 mask)
-{
- if (mask & 0x0000ffff) memory_write_word_masked_16le(space, address + 0, data >> 0, mask >> 0);
- if (mask & 0xffff0000) memory_write_word_masked_16le(space, address + 2, data >> 16, mask >> 16);
-}
+//-------------------------------------------------
+// set_delegate - set a 16-bit delegate, and
+// configure a stub if necessary
+//-------------------------------------------------
-void memory_write_dword_16be(const address_space *space, offs_t address, UINT32 data)
+void handler_entry_read::set_delegate(read16_delegate delegate, UINT64 mask)
{
- memory_write_word_16be(space, address + 0, data >> 16);
- memory_write_word_16be(space, address + 2, data >> 0);
-}
+ // error if no object
+ if (!delegate.has_object())
+ throw emu_fatalerror("Attempted to install delegate '%s' without a bound object", delegate.name());
-void memory_write_dword_masked_16be(const address_space *space, offs_t address, UINT32 data, UINT32 mask)
-{
- if (mask & 0xffff0000) memory_write_word_masked_16be(space, address + 0, data >> 16, mask >> 16);
- if (mask & 0x0000ffff) memory_write_word_masked_16be(space, address + 2, data >> 0, mask >> 0);
-}
+ // make sure this is a valid size
+ assert(m_datawidth >= 16);
+ m_read16 = delegate;
-void memory_write_qword_16le(const address_space *space, offs_t address, UINT64 data)
-{
- memory_write_dword_16le(space, address + 0, data >> 0);
- memory_write_dword_16le(space, address + 4, data >> 32);
+ // if mismatched bus width, configure a stub
+ if (m_datawidth != 16)
+ {
+ configure_subunits(mask, 16);
+ if (m_datawidth == 32)
+ set_delegate(read32_delegate(read32_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_32_from_16>(delegate.name()), *this));
+ else if (m_datawidth == 64)
+ set_delegate(read64_delegate(read64_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_64_from_16>(delegate.name()), *this));
+ }
}
-void memory_write_qword_masked_16le(const address_space *space, offs_t address, UINT64 data, UINT64 mask)
-{
- if (mask & U64(0x00000000ffffffff)) memory_write_dword_masked_16le(space, address + 0, data >> 0, mask >> 0);
- if (mask & U64(0xffffffff00000000)) memory_write_dword_masked_16le(space, address + 4, data >> 32, mask >> 32);
-}
-void memory_write_qword_16be(const address_space *space, offs_t address, UINT64 data)
-{
- memory_write_dword_16be(space, address + 0, data >> 32);
- memory_write_dword_16be(space, address + 4, data >> 0);
-}
+//-------------------------------------------------
+// set_delegate - set a 32-bit delegate, and
+// configure a stub if necessary
+//-------------------------------------------------
-void memory_write_qword_masked_16be(const address_space *space, offs_t address, UINT64 data, UINT64 mask)
+void handler_entry_read::set_delegate(read32_delegate delegate, UINT64 mask)
{
- if (mask & U64(0xffffffff00000000)) memory_write_dword_masked_16be(space, address + 0, data >> 32, mask >> 32);
- if (mask & U64(0x00000000ffffffff)) memory_write_dword_masked_16be(space, address + 4, data >> 0, mask >> 0);
-}
+ // error if no object
+ if (!delegate.has_object())
+ throw emu_fatalerror("Attempted to install delegate '%s' without a bound object", delegate.name());
+ // make sure this is a valid size
+ assert(m_datawidth >= 32);
+ m_read32 = delegate;
+
+ // if mismatched bus width, configure a stub
+ if (m_datawidth != 32)
+ {
+ configure_subunits(mask, 16);
+ if (m_datawidth == 64)
+ set_delegate(read64_delegate(read64_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_64_from_32>(delegate.name()), *this));
+ }
+}
-/***************************************************************************
- 32-BIT READ HANDLERS
-***************************************************************************/
+//-------------------------------------------------
+// set_delegate - set a 64-bit delegate
+//-------------------------------------------------
-UINT8 memory_read_byte_32le(const address_space *space, offs_t address)
+void handler_entry_read::set_delegate(read64_delegate delegate, UINT64 mask)
{
- UINT32 shift = (address & 3) * 8;
- return read_dword_generic(space, address, 0xff << shift) >> shift;
-}
+ // error if no object
+ if (!delegate.has_object())
+ throw emu_fatalerror("Attempted to install delegate '%s' without a bound object", delegate.name());
-UINT8 memory_read_byte_32be(const address_space *space, offs_t address)
-{
- UINT32 shift = (~address & 3) * 8;
- return read_dword_generic(space, address, 0xff << shift) >> shift;
+ // make sure this is a valid size
+ assert(m_datawidth >= 64);
+ m_read64 = delegate;
}
-UINT16 memory_read_word_32le(const address_space *space, offs_t address)
+
+//-------------------------------------------------
+// set_legacy_func - configure a legacy address
+// space stub of the appropriate size
+//-------------------------------------------------
+
+void handler_entry_read::set_legacy_func(const address_space &space, read8_space_func func, const char *name, UINT64 mask)
{
- UINT32 shift = (address & 2) * 8;
- return read_dword_generic(space, address, 0xffff << shift) >> shift;
+ m_legacy_handler.space8 = func;
+ m_legacy_object.space = &space;
+ set_delegate(read8_delegate(read8_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_legacy>(name), *this), mask);
}
-UINT16 memory_read_word_masked_32le(const address_space *space, offs_t address, UINT16 mask)
+void handler_entry_read::set_legacy_func(const address_space &space, read16_space_func func, const char *name, UINT64 mask)
{
- UINT32 shift = (address & 2) * 8;
- return read_dword_generic(space, address, mask << shift) >> shift;
+ m_legacy_handler.space16 = func;
+ m_legacy_object.space = &space;
+ set_delegate(read16_delegate(read16_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_legacy>(name), *this), mask);
}
-UINT16 memory_read_word_32be(const address_space *space, offs_t address)
+void handler_entry_read::set_legacy_func(const address_space &space, read32_space_func func, const char *name, UINT64 mask)
{
- UINT32 shift = (~address & 2) * 8;
- return read_dword_generic(space, address, 0xffff << shift) >> shift;
+ m_legacy_handler.space32 = func;
+ m_legacy_object.space = &space;
+ set_delegate(read32_delegate(read32_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_legacy>(name), *this), mask);
}
-UINT16 memory_read_word_masked_32be(const address_space *space, offs_t address, UINT16 mask)
+void handler_entry_read::set_legacy_func(const address_space &space, read64_space_func func, const char *name, UINT64 mask)
{
- UINT32 shift = (~address & 2) * 8;
- return read_dword_generic(space, address, mask << shift) >> shift;
+ m_legacy_handler.space64 = func;
+ m_legacy_object.space = &space;
+ set_delegate(read64_delegate(read64_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_legacy>(name), *this), mask);
}
-UINT32 memory_read_dword_32le(const address_space *space, offs_t address)
+
+//-------------------------------------------------
+// set_legacy_func - configure a legacy device
+// stub of the appropriate size
+//-------------------------------------------------
+
+void handler_entry_read::set_legacy_func(device_t &device, read8_device_func func, const char *name, UINT64 mask)
{
- return read_dword_generic(space, address, 0xffffffff);
+ m_legacy_handler.device8 = func;
+ m_legacy_object.device = &device;
+ set_delegate(read8_delegate(read8_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_legacy>(name), *this), mask);
}
-UINT32 memory_read_dword_masked_32le(const address_space *space, offs_t address, UINT32 mask)
+void handler_entry_read::set_legacy_func(device_t &device, read16_device_func func, const char *name, UINT64 mask)
{
- return read_dword_generic(space, address, mask);
+ m_legacy_handler.device16 = func;
+ m_legacy_object.device = &device;
+ set_delegate(read16_delegate(read16_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_legacy>(name), *this), mask);
}
-UINT32 memory_read_dword_32be(const address_space *space, offs_t address)
+void handler_entry_read::set_legacy_func(device_t &device, read32_device_func func, const char *name, UINT64 mask)
{
- return read_dword_generic(space, address, 0xffffffff);
+ m_legacy_handler.device32 = func;
+ m_legacy_object.device = &device;
+ set_delegate(read32_delegate(read32_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_legacy>(name), *this), mask);
}
-UINT32 memory_read_dword_masked_32be(const address_space *space, offs_t address, UINT32 mask)
+void handler_entry_read::set_legacy_func(device_t &device, read64_device_func func, const char *name, UINT64 mask)
{
- return read_dword_generic(space, address, mask);
+ m_legacy_handler.device64 = func;
+ m_legacy_object.device = &device;
+ set_delegate(read64_delegate(read64_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_legacy>(name), *this), mask);
}
-UINT64 memory_read_qword_32le(const address_space *space, offs_t address)
+
+//-------------------------------------------------
+// set_ioport - configure an I/O port read stub
+// of the appropriate size
+//-------------------------------------------------
+
+void handler_entry_read::set_ioport(const input_port_config &ioport)
{
- UINT64 result = (UINT64)memory_read_dword_32le(space, address + 0) << 0;
- return result | ((UINT64)memory_read_dword_32le(space, address + 4) << 32);
+ m_ioport = &ioport;
+ if (m_datawidth == 8)
+ set_delegate(read8_delegate(read8_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_ioport<UINT8> >(ioport.tag), *this));
+ else if (m_datawidth == 16)
+ set_delegate(read16_delegate(read16_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_ioport<UINT16> >(ioport.tag), *this));
+ else if (m_datawidth == 32)
+ set_delegate(read32_delegate(read32_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_ioport<UINT32> >(ioport.tag), *this));
+ else if (m_datawidth == 64)
+ set_delegate(read64_delegate(read64_proto_delegate::_create_member<handler_entry_read, &handler_entry_read::read_stub_ioport<UINT64> >(ioport.tag), *this));
}
-UINT64 memory_read_qword_masked_32le(const address_space *space, offs_t address, UINT64 mask)
+
+//-------------------------------------------------
+// read_stub_16_from_8 - construct a 16-bit read
+// from 8-bit sources
+//-------------------------------------------------
+
+UINT16 handler_entry_read::read_stub_16_from_8(address_space &space, offs_t offset, UINT16 mask)
{
- UINT64 result = 0;
- if (mask & U64(0x00000000ffffffff)) result |= (UINT64)memory_read_dword_masked_32le(space, address + 0, mask >> 0) << 0;
- if (mask & U64(0xffffffff00000000)) result |= (UINT64)memory_read_dword_masked_32le(space, address + 4, mask >> 32) << 32;
+ UINT16 result = 0;
+ for (int index = 0; index < m_subunits; index++)
+ {
+ int shift = m_subshift[index];
+ UINT8 mask8 = mask >> shift;
+ if (mask8 != 0)
+ result |= m_read8(space, offset * m_subunits + index, mask8) << shift;
+ }
return result;
}
-UINT64 memory_read_qword_32be(const address_space *space, offs_t address)
+
+//-------------------------------------------------
+// read_stub_32_from_8 - construct a 32-bit read
+// from 8-bit sources
+//-------------------------------------------------
+
+UINT32 handler_entry_read::read_stub_32_from_8(address_space &space, offs_t offset, UINT32 mask)
{
- UINT64 result = (UINT64)memory_read_dword_32be(space, address + 0) << 32;
- return result | ((UINT64)memory_read_dword_32be(space, address + 4) << 0);
+ UINT32 result = 0;
+ for (int index = 0; index < m_subunits; index++)
+ {
+ int shift = m_subshift[index];
+ UINT8 mask8 = mask >> shift;
+ if (mask8 != 0)
+ result |= m_read8(space, offset * m_subunits + index, mask8) << shift;
+ }
+ return result;
}
-UINT64 memory_read_qword_masked_32be(const address_space *space, offs_t address, UINT64 mask)
+
+//-------------------------------------------------
+// read_stub_64_from_8 - construct a 64-bit read
+// from 8-bit sources
+//-------------------------------------------------
+
+UINT64 handler_entry_read::read_stub_64_from_8(address_space &space, offs_t offset, UINT64 mask)
{
UINT64 result = 0;
- if (mask & U64(0xffffffff00000000)) result |= (UINT64)memory_read_dword_masked_32be(space, address + 0, mask >> 32) << 32;
- if (mask & U64(0x00000000ffffffff)) result |= (UINT64)memory_read_dword_masked_32be(space, address + 4, mask >> 0) << 0;
+ for (int index = 0; index < m_subunits; index++)
+ {
+ int shift = m_subshift[index];
+ UINT8 mask8 = mask >> shift;
+ if (mask8 != 0)
+ result |= (UINT64)m_read8(space, offset * m_subunits + index, mask8) << shift;
+ }
return result;
}
+//-------------------------------------------------
+// read_stub_32_from_16 - construct a 32-bit read
+// from 16-bit sources
+//-------------------------------------------------
-/***************************************************************************
- 32-BIT WRITE HANDLERS
-***************************************************************************/
-
-void memory_write_byte_32le(const address_space *space, offs_t address, UINT8 data)
+UINT32 handler_entry_read::read_stub_32_from_16(address_space &space, offs_t offset, UINT32 mask)
{
- UINT32 shift = (address & 3) * 8;
- write_dword_generic(space, address, data << shift, 0xff << shift);
+ UINT32 result = 0;
+ for (int index = 0; index < m_subunits; index++)
+ {
+ int shift = m_subshift[index];
+ UINT16 mask16 = mask >> shift;
+ if (mask16 != 0)
+ result |= m_read16(space, offset * m_subunits + index, mask16) << shift;
+ }
+ return result;
}
-void memory_write_byte_32be(const address_space *space, offs_t address, UINT8 data)
-{
- UINT32 shift = (~address & 3) * 8;
- write_dword_generic(space, address, data << shift, 0xff << shift);
-}
-void memory_write_word_32le(const address_space *space, offs_t address, UINT16 data)
-{
- UINT32 shift = (address & 2) * 8;
- write_dword_generic(space, address, data << shift, 0xffff << shift);
-}
+//-------------------------------------------------
+// read_stub_64_from_16 - construct a 64-bit read
+// from 16-bit sources
+//-------------------------------------------------
-void memory_write_word_masked_32le(const address_space *space, offs_t address, UINT16 data, UINT16 mask)
+UINT64 handler_entry_read::read_stub_64_from_16(address_space &space, offs_t offset, UINT64 mask)
{
- UINT32 shift = (address & 2) * 8;
- write_dword_generic(space, address, data << shift, mask << shift);
+ UINT64 result = 0;
+ for (int index = 0; index < m_subunits; index++)
+ {
+ int shift = m_subshift[index];
+ UINT16 mask16 = mask >> shift;
+ if (mask16 != 0)
+ result |= (UINT64)m_read16(space, offset * m_subunits + index, mask16) << shift;
+ }
+ return result;
}
-void memory_write_word_32be(const address_space *space, offs_t address, UINT16 data)
-{
- UINT32 shift = (~address & 2) * 8;
- write_dword_generic(space, address, data << shift, 0xffff << shift);
-}
-void memory_write_word_masked_32be(const address_space *space, offs_t address, UINT16 data, UINT16 mask)
-{
- UINT32 shift = (~address & 2) * 8;
- write_dword_generic(space, address, data << shift, mask << shift);
-}
+//-------------------------------------------------
+// read_stub_64_from_32 - construct a 64-bit read
+// from 32-bit sources
+//-------------------------------------------------
-void memory_write_dword_32le(const address_space *space, offs_t address, UINT32 data)
+UINT64 handler_entry_read::read_stub_64_from_32(address_space &space, offs_t offset, UINT64 mask)
{
- write_dword_generic(space, address, data, 0xffffffff);
+ UINT64 result = 0;
+ for (int index = 0; index < m_subunits; index++)
+ {
+ int shift = m_subshift[index];
+ UINT32 mask32 = mask >> shift;
+ if (mask32 != 0)
+ result |= (UINT64)m_read32(space, offset * m_subunits + index, mask32) << shift;
+ }
+ return result;
}
-void memory_write_dword_masked_32le(const address_space *space, offs_t address, UINT32 data, UINT32 mask)
-{
- write_dword_generic(space, address, data, mask);
-}
-void memory_write_dword_32be(const address_space *space, offs_t address, UINT32 data)
-{
- write_dword_generic(space, address, data, 0xffffffff);
-}
+//-------------------------------------------------
+// read_stub_legacy - perform a read using legacy
+// handler callbacks
+//-------------------------------------------------
-void memory_write_dword_masked_32be(const address_space *space, offs_t address, UINT32 data, UINT32 mask)
+UINT8 handler_entry_read::read_stub_legacy(address_space &space, offs_t offset, UINT8 mask)
{
- write_dword_generic(space, address, data, mask);
+ return m_legacy_handler.space8(m_legacy_object.space, offset);
}
-void memory_write_qword_32le(const address_space *space, offs_t address, UINT64 data)
+UINT16 handler_entry_read::read_stub_legacy(address_space &space, offs_t offset, UINT16 mask)
{
- memory_write_dword_32le(space, address + 0, data >> 0);
- memory_write_dword_32le(space, address + 4, data >> 32);
+ return m_legacy_handler.space16(m_legacy_object.space, offset, mask);
}
-void memory_write_qword_masked_32le(const address_space *space, offs_t address, UINT64 data, UINT64 mask)
+UINT32 handler_entry_read::read_stub_legacy(address_space &space, offs_t offset, UINT32 mask)
{
- if (mask & U64(0x00000000ffffffff)) memory_write_dword_masked_32le(space, address + 0, data >> 0, mask >> 0);
- if (mask & U64(0xffffffff00000000)) memory_write_dword_masked_32le(space, address + 4, data >> 32, mask >> 32);
+ return m_legacy_handler.space32(m_legacy_object.space, offset, mask);
}
-void memory_write_qword_32be(const address_space *space, offs_t address, UINT64 data)
+UINT64 handler_entry_read::read_stub_legacy(address_space &space, offs_t offset, UINT64 mask)
{
- memory_write_dword_32be(space, address + 0, data >> 32);
- memory_write_dword_32be(space, address + 4, data >> 0);
+ return m_legacy_handler.space64(m_legacy_object.space, offset, mask);
}
-void memory_write_qword_masked_32be(const address_space *space, offs_t address, UINT64 data, UINT64 mask)
-{
- if (mask & U64(0xffffffff00000000)) memory_write_dword_masked_32be(space, address + 0, data >> 32, mask >> 32);
- if (mask & U64(0x00000000ffffffff)) memory_write_dword_masked_32be(space, address + 4, data >> 0, mask >> 0);
-}
+//**************************************************************************
+// HANDLER ENTRY WRITE
+//**************************************************************************
-/***************************************************************************
- 64-BIT READ HANDLERS
-***************************************************************************/
+//-------------------------------------------------
+// name - return the handler name, from the
+// appropriately-sized delegate
+//-------------------------------------------------
-UINT8 memory_read_byte_64le(const address_space *space, offs_t address)
+const char *handler_entry_write::name() const
{
- UINT32 shift = (address & 7) * 8;
- return read_qword_generic(space, address, (UINT64)0xff << shift) >> shift;
+ switch (m_datawidth)
+ {
+ case 8: return m_write8.name();
+ case 16: return m_write16.name();
+ case 32: return m_write32.name();
+ case 64: return m_write64.name();
+ }
+ return NULL;
}
-UINT8 memory_read_byte_64be(const address_space *space, offs_t address)
-{
- UINT32 shift = (~address & 7) * 8;
- return read_qword_generic(space, address, (UINT64)0xff << shift) >> shift;
-}
-UINT16 memory_read_word_64le(const address_space *space, offs_t address)
+//-------------------------------------------------
+// set_delegate - set an 8-bit delegate, and
+// configure a stub if necessary
+//-------------------------------------------------
+
+void handler_entry_write::set_delegate(write8_delegate delegate, UINT64 mask)
{
- UINT32 shift = (address & 6) * 8;
- return read_qword_generic(space, address, (UINT64)0xffff << shift) >> shift;
+ assert(m_datawidth >= 8);
+ m_write8 = delegate;
+
+ // if mismatched bus width, configure a stub
+ if (m_datawidth != 8)
+ {
+ configure_subunits(mask, 8);
+ if (m_datawidth == 16)
+ set_delegate(write16_delegate(write16_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_16_from_8>(delegate.name()), *this));
+ else if (m_datawidth == 32)
+ set_delegate(write32_delegate(write32_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_32_from_8>(delegate.name()), *this));
+ else if (m_datawidth == 64)
+ set_delegate(write64_delegate(write64_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_64_from_8>(delegate.name()), *this));
+ }
}
-UINT16 memory_read_word_masked_64le(const address_space *space, offs_t address, UINT16 mask)
+
+//-------------------------------------------------
+// set_delegate - set a 16-bit delegate, and
+// configure a stub if necessary
+//-------------------------------------------------
+
+void handler_entry_write::set_delegate(write16_delegate delegate, UINT64 mask)
{
- UINT32 shift = (address & 6) * 8;
- return read_qword_generic(space, address, (UINT64)mask << shift) >> shift;
+ assert(m_datawidth >= 16);
+ m_write16 = delegate;
+
+ // if mismatched bus width, configure a stub
+ if (m_datawidth != 16)
+ {
+ configure_subunits(mask, 16);
+ if (m_datawidth == 32)
+ set_delegate(write32_delegate(write32_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_32_from_16>(delegate.name()), *this));
+ else if (m_datawidth == 64)
+ set_delegate(write64_delegate(write64_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_64_from_16>(delegate.name()), *this));
+ }
}
-UINT16 memory_read_word_64be(const address_space *space, offs_t address)
+
+//-------------------------------------------------
+// set_delegate - set a 32-bit delegate, and
+// configure a stub if necessary
+//-------------------------------------------------
+
+void handler_entry_write::set_delegate(write32_delegate delegate, UINT64 mask)
{
- UINT32 shift = (~address & 6) * 8;
- return read_qword_generic(space, address, (UINT64)0xffff << shift) >> shift;
+ assert(m_datawidth >= 32);
+ m_write32 = delegate;
+
+ // if mismatched bus width, configure a stub
+ if (m_datawidth != 32)
+ {
+ configure_subunits(mask, 16);
+ if (m_datawidth == 64)
+ set_delegate(write64_delegate(write64_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_64_from_32>(delegate.name()), *this));
+ }
}
-UINT16 memory_read_word_masked_64be(const address_space *space, offs_t address, UINT16 mask)
+
+//-------------------------------------------------
+// set_delegate - set a 64-bit delegate
+//-------------------------------------------------
+
+void handler_entry_write::set_delegate(write64_delegate delegate, UINT64 mask)
{
- UINT32 shift = (~address & 6) * 8;
- return read_qword_generic(space, address, (UINT64)mask << shift) >> shift;
+ assert(m_datawidth >= 64);
+ m_write64 = delegate;
}
-UINT32 memory_read_dword_64le(const address_space *space, offs_t address)
+
+//-------------------------------------------------
+// set_legacy_func - configure a legacy address
+// space stub of the appropriate size
+//-------------------------------------------------
+
+void handler_entry_write::set_legacy_func(const address_space &space, write8_space_func func, const char *name, UINT64 mask)
{
- UINT32 shift = (address & 4) * 8;
- return read_qword_generic(space, address, (UINT64)0xffffffff << shift) >> shift;
+ m_legacy_handler.space8 = func;
+ m_legacy_object.space = &space;
+ set_delegate(write8_delegate(write8_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_legacy>(name), *this), mask);
}
-UINT32 memory_read_dword_masked_64le(const address_space *space, offs_t address, UINT32 mask)
+void handler_entry_write::set_legacy_func(const address_space &space, write16_space_func func, const char *name, UINT64 mask)
{
- UINT32 shift = (address & 4) * 8;
- return read_qword_generic(space, address, (UINT64)mask << shift) >> shift;
+ m_legacy_handler.space16 = func;
+ m_legacy_object.space = &space;
+ set_delegate(write16_delegate(write16_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_legacy>(name), *this), mask);
}
-UINT32 memory_read_dword_64be(const address_space *space, offs_t address)
+void handler_entry_write::set_legacy_func(const address_space &space, write32_space_func func, const char *name, UINT64 mask)
{
- UINT32 shift = (~address & 4) * 8;
- return read_qword_generic(space, address, (UINT64)0xffffffff << shift) >> shift;
+ m_legacy_handler.space32 = func;
+ m_legacy_object.space = &space;
+ set_delegate(write32_delegate(write32_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_legacy>(name), *this), mask);
}
-UINT32 memory_read_dword_masked_64be(const address_space *space, offs_t address, UINT32 mask)
+void handler_entry_write::set_legacy_func(const address_space &space, write64_space_func func, const char *name, UINT64 mask)
{
- UINT32 shift = (~address & 4) * 8;
- return read_qword_generic(space, address, (UINT64)mask << shift) >> shift;
+ m_legacy_handler.space64 = func;
+ m_legacy_object.space = &space;
+ set_delegate(write64_delegate(write64_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_legacy>(name), *this), mask);
}
-UINT64 memory_read_qword_64le(const address_space *space, offs_t address)
+
+//-------------------------------------------------
+// set_legacy_func - configure a legacy device
+// stub of the appropriate size
+//-------------------------------------------------
+
+void handler_entry_write::set_legacy_func(device_t &device, write8_device_func func, const char *name, UINT64 mask)
{
- return read_qword_generic(space, address, U64(0xffffffffffffffff));
+ m_legacy_handler.device8 = func;
+ m_legacy_object.device = &device;
+ set_delegate(write8_delegate(write8_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_legacy>(name), *this), mask);
}
-UINT64 memory_read_qword_masked_64le(const address_space *space, offs_t address, UINT64 mask)
+void handler_entry_write::set_legacy_func(device_t &device, write16_device_func func, const char *name, UINT64 mask)
{
- return read_qword_generic(space, address, mask);
+ m_legacy_handler.device16 = func;
+ m_legacy_object.device = &device;
+ set_delegate(write16_delegate(write16_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_legacy>(name), *this), mask);
}
-UINT64 memory_read_qword_64be(const address_space *space, offs_t address)
+void handler_entry_write::set_legacy_func(device_t &device, write32_device_func func, const char *name, UINT64 mask)
{
- return read_qword_generic(space, address, U64(0xffffffffffffffff));
+ m_legacy_handler.device32 = func;
+ m_legacy_object.device = &device;
+ set_delegate(write32_delegate(write32_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_legacy>(name), *this), mask);
}
-UINT64 memory_read_qword_masked_64be(const address_space *space, offs_t address, UINT64 mask)
+void handler_entry_write::set_legacy_func(device_t &device, write64_device_func func, const char *name, UINT64 mask)
{
- return read_qword_generic(space, address, mask);
+ m_legacy_handler.device64 = func;
+ m_legacy_object.device = &device;
+ set_delegate(write64_delegate(write64_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_legacy>(name), *this), mask);
}
+//-------------------------------------------------
+// set_ioport - configure an I/O port read stub
+// of the appropriate size
+//-------------------------------------------------
-/***************************************************************************
- 64-BIT WRITE HANDLERS
-***************************************************************************/
-
-void memory_write_byte_64le(const address_space *space, offs_t address, UINT8 data)
+void handler_entry_write::set_ioport(const input_port_config &ioport)
{
- UINT32 shift = (address & 7) * 8;
- write_qword_generic(space, address, (UINT64)data << shift, (UINT64)0xff << shift);
+ m_ioport = &ioport;
+ if (m_datawidth == 8)
+ set_delegate(write8_delegate(write8_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_ioport<UINT8> >(ioport.tag), *this));
+ else if (m_datawidth == 16)
+ set_delegate(write16_delegate(write16_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_ioport<UINT16> >(ioport.tag), *this));
+ else if (m_datawidth == 32)
+ set_delegate(write32_delegate(write32_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_ioport<UINT32> >(ioport.tag), *this));
+ else if (m_datawidth == 64)
+ set_delegate(write64_delegate(write64_proto_delegate::_create_member<handler_entry_write, &handler_entry_write::write_stub_ioport<UINT64> >(ioport.tag), *this));
}
-void memory_write_byte_64be(const address_space *space, offs_t address, UINT8 data)
-{
- UINT32 shift = (~address & 7) * 8;
- write_qword_generic(space, address, (UINT64)data << shift, (UINT64)0xff << shift);
-}
-void memory_write_word_64le(const address_space *space, offs_t address, UINT16 data)
-{
- UINT32 shift = (address & 6) * 8;
- write_qword_generic(space, address, (UINT64)data << shift, (UINT64)0xffff << shift);
-}
+//-------------------------------------------------
+// write_stub_16_from_8 - construct a 16-bit write
+// from 8-bit sources
+//-------------------------------------------------
-void memory_write_word_masked_64le(const address_space *space, offs_t address, UINT16 data, UINT16 mask)
+void handler_entry_write::write_stub_16_from_8(address_space &space, offs_t offset, UINT16 data, UINT16 mask)
{
- UINT32 shift = (address & 6) * 8;
- write_qword_generic(space, address, (UINT64)data << shift, (UINT64)mask << shift);
+ for (int index = 0; index < m_subunits; index++)
+ {
+ int shift = m_subshift[index];
+ UINT8 mask8 = mask >> shift;
+ if (mask8 != 0)
+ m_write8(space, offset * m_subunits + index, data >> shift, mask8);
+ }
}
-void memory_write_word_64be(const address_space *space, offs_t address, UINT16 data)
-{
- UINT32 shift = (~address & 6) * 8;
- write_qword_generic(space, address, (UINT64)data << shift, (UINT64)0xffff << shift);
-}
-void memory_write_word_masked_64be(const address_space *space, offs_t address, UINT16 data, UINT16 mask)
+//-------------------------------------------------
+// write_stub_32_from_8 - construct a 32-bit write
+// from 8-bit sources
+//-------------------------------------------------
+
+void handler_entry_write::write_stub_32_from_8(address_space &space, offs_t offset, UINT32 data, UINT32 mask)
{
- UINT32 shift = (~address & 6) * 8;
- write_qword_generic(space, address, (UINT64)data << shift, (UINT64)mask << shift);
+ for (int index = 0; index < m_subunits; index++)
+ {
+ int shift = m_subshift[index];
+ UINT8 mask8 = mask >> shift;
+ if (mask8 != 0)
+ m_write8(space, offset * m_subunits + index, data >> shift, mask8);
+ }
}
-void memory_write_dword_64le(const address_space *space, offs_t address, UINT32 data)
+
+//-------------------------------------------------
+// write_stub_64_from_8 - construct a 64-bit write
+// from 8-bit sources
+//-------------------------------------------------
+
+void handler_entry_write::write_stub_64_from_8(address_space &space, offs_t offset, UINT64 data, UINT64 mask)
{
- UINT32 shift = (address & 4) * 8;
- write_qword_generic(space, address, (UINT64)data << shift, (UINT64)0xffffffff << shift);
+ for (int index = 0; index < m_subunits; index++)
+ {
+ int shift = m_subshift[index];
+ UINT8 mask8 = mask >> shift;
+ if (mask8 != 0)
+ m_write8(space, offset * m_subunits + index, data >> shift, mask8);
+ }
}
-void memory_write_dword_masked_64le(const address_space *space, offs_t address, UINT32 data, UINT32 mask)
+
+//-------------------------------------------------
+// write_stub_32_from_16 - construct a 32-bit
+// write from 16-bit sources
+//-------------------------------------------------
+
+void handler_entry_write::write_stub_32_from_16(address_space &space, offs_t offset, UINT32 data, UINT32 mask)
{
- UINT32 shift = (address & 4) * 8;
- write_qword_generic(space, address, (UINT64)data << shift, (UINT64)mask << shift);
+ for (int index = 0; index < m_subunits; index++)
+ {
+ int shift = m_subshift[index];
+ UINT16 mask16 = mask >> shift;
+ if (mask16 != 0)
+ m_write16(space, offset * m_subunits + index, data >> shift, mask16);
+ }
}
-void memory_write_dword_64be(const address_space *space, offs_t address, UINT32 data)
+
+//-------------------------------------------------
+// write_stub_64_from_16 - construct a 64-bit
+// write from 16-bit sources
+//-------------------------------------------------
+
+void handler_entry_write::write_stub_64_from_16(address_space &space, offs_t offset, UINT64 data, UINT64 mask)
{
- UINT32 shift = (~address & 4) * 8;
- write_qword_generic(space, address, (UINT64)data << shift, (UINT64)0xffffffff << shift);
+ for (int index = 0; index < m_subunits; index++)
+ {
+ int shift = m_subshift[index];
+ UINT16 mask16 = mask >> shift;
+ if (mask16 != 0)
+ m_write16(space, offset * m_subunits + index, data >> shift, mask16);
+ }
}
-void memory_write_dword_masked_64be(const address_space *space, offs_t address, UINT32 data, UINT32 mask)
+
+//-------------------------------------------------
+// write_stub_64_from_32 - construct a 64-bit
+// write from 32-bit sources
+//-------------------------------------------------
+
+void handler_entry_write::write_stub_64_from_32(address_space &space, offs_t offset, UINT64 data, UINT64 mask)
{
- UINT32 shift = (~address & 4) * 8;
- write_qword_generic(space, address, (UINT64)data << shift, (UINT64)mask << shift);
+ for (int index = 0; index < m_subunits; index++)
+ {
+ int shift = m_subshift[index];
+ UINT32 mask32 = mask >> shift;
+ if (mask32 != 0)
+ m_write32(space, offset * m_subunits + index, data >> shift, mask32);
+ }
}
-void memory_write_qword_64le(const address_space *space, offs_t address, UINT64 data)
+
+//-------------------------------------------------
+// write_stub_legacy - perform a write using
+// legacy handler callbacks
+//-------------------------------------------------
+
+void handler_entry_write::write_stub_legacy(address_space &space, offs_t offset, UINT8 data, UINT8 mask)
{
- write_qword_generic(space, address, data, U64(0xffffffffffffffff));
+ m_legacy_handler.space8(m_legacy_object.space, offset, data);
}
-void memory_write_qword_masked_64le(const address_space *space, offs_t address, UINT64 data, UINT64 mask)
+void handler_entry_write::write_stub_legacy(address_space &space, offs_t offset, UINT16 data, UINT16 mask)
{
- write_qword_generic(space, address, data, mask);
+ m_legacy_handler.space16(m_legacy_object.space, offset, data, mask);
}
-void memory_write_qword_64be(const address_space *space, offs_t address, UINT64 data)
+void handler_entry_write::write_stub_legacy(address_space &space, offs_t offset, UINT32 data, UINT32 mask)
{
- write_qword_generic(space, address, data, U64(0xffffffffffffffff));
+ m_legacy_handler.space32(m_legacy_object.space, offset, data, mask);
}
-void memory_write_qword_masked_64be(const address_space *space, offs_t address, UINT64 data, UINT64 mask)
+void handler_entry_write::write_stub_legacy(address_space &space, offs_t offset, UINT64 data, UINT64 mask)
{
- write_qword_generic(space, address, data, mask);
+ m_legacy_handler.space64(m_legacy_object.space, offset, data, mask);
}
diff --git a/src/emu/memory.h b/src/emu/memory.h
index 9ee538a50f5..385d27efc2a 100644
--- a/src/emu/memory.h
+++ b/src/emu/memory.h
@@ -4,8 +4,36 @@
Functions which handle device memory accesses.
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
@@ -20,68 +48,59 @@
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
-/* address spaces */
+// address spaces
enum
{
- ADDRESS_SPACE_0, /* first address space */
- ADDRESS_SPACE_1, /* second address space */
- ADDRESS_SPACE_2, /* third address space */
- ADDRESS_SPACE_3, /* fourth address space */
- ADDRESS_SPACES /* maximum number of address spaces */
+ ADDRESS_SPACE_0, // first address space
+ ADDRESS_SPACE_1, // second address space
+ ADDRESS_SPACE_2, // third address space
+ ADDRESS_SPACE_3, // fourth address space
+ ADDRESS_SPACES // maximum number of address spaces
};
+// read or write constants
+enum read_or_write
+{
+ ROW_READ = 1,
+ ROW_WRITE = 2,
+ ROW_READWRITE = 3
+};
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-/* referenced types from other classes */
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// referenced types from other classes
+class device_memory_interface;
class device_config;
class device_t;
-class address_map;
struct game_driver;
-
-/* handler_data and subtable_data are opaque types used to hold information about a particular handler */
-typedef struct _handler_data handler_data;
-typedef struct _subtable_data subtable_data;
-
-/* direct_range is an opaque type used to track ranges for direct access */
-typedef struct _direct_range direct_range;
-
-/* forward-declare the address_space structure */
-typedef struct _address_space address_space;
+// forward declarations of classes defined here
+class address_map;
+class address_map_entry;
+class memory_bank;
+class direct_read_data;
+class address_space;
+class address_table;
+class address_table_read;
+class address_table_write;
-/* offsets and addresses are 32-bit (for now...) */
+// offsets and addresses are 32-bit (for now...)
typedef UINT32 offs_t;
-
-/* direct_read_data contains state data for direct read access */
-typedef struct _direct_read_data direct_read_data;
-struct _direct_read_data
-{
- UINT8 * raw; /* direct access data pointer (raw) */
- UINT8 * decrypted; /* direct access data pointer (decrypted) */
- offs_t bytemask; /* byte address mask */
- offs_t bytestart; /* minimum valid byte address */
- offs_t byteend; /* maximum valid byte address */
- UINT8 entry; /* live entry */
- direct_range * rangelist[256]; /* list of ranges for each entry */
- direct_range * freerangelist; /* list of recycled range entries */
-};
-
-
-/* direct region update handler */
-typedef offs_t (*direct_update_func) (ATTR_UNUSED const address_space *space, ATTR_UNUSED offs_t address, ATTR_UNUSED direct_read_data *direct);
+// address map constructors are functions that build up an address_map
+typedef void (*address_map_constructor)(address_map &map, const device_config &devconfig);
-/* space read/write handlers */
+// legacy space read/write handlers
typedef UINT8 (*read8_space_func) (ATTR_UNUSED const address_space *space, ATTR_UNUSED offs_t offset);
typedef void (*write8_space_func) (ATTR_UNUSED const address_space *space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT8 data);
typedef UINT16 (*read16_space_func) (ATTR_UNUSED const address_space *space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT16 mem_mask);
@@ -91,8 +110,7 @@ typedef void (*write32_space_func)(ATTR_UNUSED const address_space *space, ATTR_
typedef UINT64 (*read64_space_func) (ATTR_UNUSED const address_space *space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT64 mem_mask);
typedef void (*write64_space_func)(ATTR_UNUSED const address_space *space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT64 data, ATTR_UNUSED UINT64 mem_mask);
-
-/* device read/write handlers */
+// legacy device read/write handlers
typedef UINT8 (*read8_device_func) (ATTR_UNUSED device_t *device, ATTR_UNUSED offs_t offset);
typedef void (*write8_device_func) (ATTR_UNUSED device_t *device, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT8 data);
typedef UINT16 (*read16_device_func) (ATTR_UNUSED device_t *device, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT16 mem_mask);
@@ -103,9 +121,8 @@ typedef UINT64 (*read64_device_func) (ATTR_UNUSED device_t *device, ATTR_UNUSED
typedef void (*write64_device_func)(ATTR_UNUSED device_t *device, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT64 data, ATTR_UNUSED UINT64 mem_mask);
-/* data_accessors is a struct with accessors of all flavors */
-typedef struct _data_accessors data_accessors;
-struct _data_accessors
+// struct with function pointers for accessors; use is generally discouraged unless necessary
+struct data_accessors
{
UINT8 (*read_byte)(const address_space *space, offs_t byteaddress);
UINT16 (*read_word)(const address_space *space, offs_t byteaddress);
@@ -125,62 +142,375 @@ struct _data_accessors
};
-/* address_table contains information about read/write accesses within an address space */
-typedef struct _address_table address_table;
-struct _address_table
+// ======================> direct_update_delegate
+
+// direct region update handler
+typedef proto_delegate_2param<offs_t, direct_read_data &, offs_t> direct_update_proto_delegate;
+typedef delegate_2param<offs_t, direct_read_data &, offs_t> direct_update_delegate;
+
+#define direct_update_delegate_create(_Class, _Method, _Object) direct_update_delegate(direct_update_proto_delegate::_create_member<_Class, &_Class::_Method>(#_Class "::" #_Method), _Object)
+#define direct_update_delegate_create_static(_Function, _Object) direct_update_delegate(direct_update_proto_delegate::_create_static<running_machine, &_Function>(#_Function), _Object)
+
+
+// ======================> read_delegate
+
+// declare proto-delegates for each width
+typedef proto_delegate_3param<UINT8, address_space &, offs_t, UINT8> read8_proto_delegate;
+typedef proto_delegate_3param<UINT16, address_space &, offs_t, UINT16> read16_proto_delegate;
+typedef proto_delegate_3param<UINT32, address_space &, offs_t, UINT32> read32_proto_delegate;
+typedef proto_delegate_3param<UINT64, address_space &, offs_t, UINT64> read64_proto_delegate;
+
+// declare delegates for each width
+typedef delegate_3param<UINT8, address_space &, offs_t, UINT8> read8_delegate;
+typedef delegate_3param<UINT16, address_space &, offs_t, UINT16> read16_delegate;
+typedef delegate_3param<UINT32, address_space &, offs_t, UINT32> read32_delegate;
+typedef delegate_3param<UINT64, address_space &, offs_t, UINT64> read64_delegate;
+
+// macros for creating read proto-delegates
+#define read8_proto_delegate_create(_Class, _Method) read8_proto_delegate::_create_member<_Class, &_Class::_Method>(#_Class "::" #_Method)
+#define read16_proto_delegate_create(_Class, _Method) read16_proto_delegate::_create_member<_Class, &_Class::_Method>(#_Class "::" #_Method)
+#define read32_proto_delegate_create(_Class, _Method) read32_proto_delegate::_create_member<_Class, &_Class::_Method>(#_Class "::" #_Method)
+#define read64_proto_delegate_create(_Class, _Method) read64_proto_delegate::_create_member<_Class, &_Class::_Method>(#_Class "::" #_Method)
+
+// macros for creating read delegates, bound to the provided object
+#define read8_delegate_create(_Class, _Method, _Object) read8_delegate(read8_proto_delegate_create(_Class, _Method), _Object)
+#define read16_delegate_create(_Class, _Method, _Object) read16_delegate(read16_proto_delegate_create(_Class, _Method), _Object)
+#define read32_delegate_create(_Class, _Method, _Object) read32_delegate(read32_proto_delegate_create(_Class, _Method), _Object)
+#define read64_delegate_create(_Class, _Method, _Object) read64_delegate(read64_proto_delegate_create(_Class, _Method), _Object)
+
+
+// ======================> write_delegate
+
+// declare proto-delegates for each width
+typedef proto_delegate_4param<void, address_space &, offs_t, UINT8, UINT8> write8_proto_delegate;
+typedef proto_delegate_4param<void, address_space &, offs_t, UINT16, UINT16> write16_proto_delegate;
+typedef proto_delegate_4param<void, address_space &, offs_t, UINT32, UINT32> write32_proto_delegate;
+typedef proto_delegate_4param<void, address_space &, offs_t, UINT64, UINT64> write64_proto_delegate;
+
+// declare delegates for each width
+typedef delegate_4param<void, address_space &, offs_t, UINT8, UINT8> write8_delegate;
+typedef delegate_4param<void, address_space &, offs_t, UINT16, UINT16> write16_delegate;
+typedef delegate_4param<void, address_space &, offs_t, UINT32, UINT32> write32_delegate;
+typedef delegate_4param<void, address_space &, offs_t, UINT64, UINT64> write64_delegate;
+
+// macros for creating write proto-delegates
+#define write8_proto_delegate_create(_Class, _Method) write8_proto_delegate::_create_member<_Class, &_Class::_Method>(#_Class "::" #_Method)
+#define write16_proto_delegate_create(_Class, _Method) write16_proto_delegate::_create_member<_Class, &_Class::_Method>(#_Class "::" #_Method)
+#define write32_proto_delegate_create(_Class, _Method) write32_proto_delegate::_create_member<_Class, &_Class::_Method>(#_Class "::" #_Method)
+#define write64_proto_delegate_create(_Class, _Method) write64_proto_delegate::_create_member<_Class, &_Class::_Method>(#_Class "::" #_Method)
+
+// macros for creating write delegates, bound to the provided object
+#define write8_delegate_create(_Class, _Method, _Object) write8_delegate(write8_proto_delegate::_create_member<_Class, &_Class::_Method>(#_Class "::" #_Method), _Object)
+#define write16_delegate_create(_Class, _Method, _Object) write16_delegate(write16_proto_delegate::_create_member<_Class, &_Class::_Method>(#_Class "::" #_Method), _Object)
+#define write32_delegate_create(_Class, _Method, _Object) write32_delegate(write32_proto_delegate::_create_member<_Class, &_Class::_Method>(#_Class "::" #_Method), _Object)
+#define write64_delegate_create(_Class, _Method, _Object) write64_delegate(write64_proto_delegate::_create_member<_Class, &_Class::_Method>(#_Class "::" #_Method), _Object)
+
+
+// ======================> direct_read_data
+
+// direct_read_data contains state data for direct read access
+class direct_read_data
{
- UINT8 * table; /* pointer to base of table */
- UINT8 subtable_alloc; /* number of subtables allocated */
- subtable_data * subtable; /* info about each subtable */
- handler_data * handlers[256]; /* array of user-installed handlers */
- running_machine * machine; /* pointer back to the machine */
+ friend class address_table;
+
+public:
+ // direct_range is an internal class that is part of a list of start/end ranges
+ class direct_range
+ {
+ public:
+ // construction
+ direct_range()
+ : m_next(NULL),
+ m_bytestart(0),
+ m_byteend(~0) { }
+
+ // getters
+ direct_range *next() const { return m_next; }
+
+ // internal state
+ direct_range * m_next; // pointer to the next range in the list
+ offs_t m_bytestart; // starting byte offset of the range
+ offs_t m_byteend; // ending byte offset of the range
+ };
+
+ // construction/destruction
+ direct_read_data(address_space &space);
+ ~direct_read_data();
+
+ // getters
+ address_space &space() const { return m_space; }
+ UINT8 *raw() const { return m_raw; }
+ UINT8 *decrypted() const { return m_decrypted; }
+
+ // see if an address is within bounds, or attempt to update it if not
+ bool address_is_valid(offs_t byteaddress) { return EXPECTED(byteaddress >= m_bytestart && byteaddress <= m_byteend) || set_direct_region(byteaddress); }
+
+ // force a recomputation on the next read
+ void force_update() { m_byteend = 0; m_bytestart = 1; }
+ void force_update(UINT8 if_match) { if (m_entry == if_match) force_update(); }
+
+ // custom update callbacks and configuration
+ direct_update_delegate set_direct_update(direct_update_delegate function);
+ void explicit_configure(offs_t bytestart, offs_t byteend, offs_t bytemask, void *raw, void *decrypted = NULL);
+
+ // accessor methods for reading raw data
+ void *read_raw_ptr(offs_t byteaddress);
+ UINT8 read_raw_byte(offs_t byteaddress);
+ UINT16 read_raw_word(offs_t byteaddress);
+ UINT32 read_raw_dword(offs_t byteaddress);
+ UINT64 read_raw_qword(offs_t byteaddress);
+
+ // accessor methods for reading decrypted data
+ void *read_decrypted_ptr(offs_t byteaddress);
+ UINT8 read_decrypted_byte(offs_t byteaddress);
+ UINT16 read_decrypted_word(offs_t byteaddress);
+ UINT32 read_decrypted_dword(offs_t byteaddress);
+ UINT64 read_decrypted_qword(offs_t byteaddress);
+
+private:
+ // internal helpers
+ bool set_direct_region(offs_t &byteaddress);
+ direct_range *find_range(offs_t byteaddress, UINT8 &entry);
+ void remove_intersecting_ranges(offs_t bytestart, offs_t byteend);
+
+ // internal state
+ address_space & m_space;
+ UINT8 * m_raw; // direct access data pointer (raw)
+ UINT8 * m_decrypted; // direct access data pointer (decrypted)
+ offs_t m_bytemask; // byte address mask
+ offs_t m_bytestart; // minimum valid byte address
+ offs_t m_byteend; // maximum valid byte address
+ UINT8 m_entry; // live entry
+ simple_list<direct_range> m_rangelist[256]; // list of ranges for each entry
+ simple_list<direct_range> m_freerangelist; // list of recycled range entries
+ direct_update_delegate m_directupdate; // fast direct-access update callback
};
-/* address_space holds live information about an address space */
-/* Declared above: typedef struct _address_space address_space; */
-struct _address_space
-{
- address_space * next; /* next address space in the global list */
- running_machine * machine; /* reference to the owning machine */
- device_t * cpu; /* reference to the owning device */
- const device_config * devconfig; /* pointer to the owning device's config */
- address_map * map; /* original memory map */
- const char * name; /* friendly name of the address space */
- UINT8 * readlookup; /* live lookup table for reads */
- UINT8 * writelookup; /* live lookup table for writes */
- data_accessors accessors; /* data access handlers */
- direct_read_data direct; /* fast direct-access read info */
- direct_update_func directupdate; /* fast direct-access update callback */
- UINT64 unmap; /* unmapped value */
- offs_t addrmask; /* physical address mask */
- offs_t bytemask; /* byte-converted physical address mask */
- offs_t logaddrmask; /* logical address mask */
- offs_t logbytemask; /* byte-converted logical address mask */
- UINT8 spacenum; /* address space index */
- endianness_t endianness; /* endianness of this space */
- INT8 ashift; /* address shift */
- UINT8 abits; /* address bits */
- UINT8 dbits; /* data bits */
- UINT8 addrchars; /* number of characters to use for physical addresses */
- UINT8 logaddrchars; /* number of characters to use for logical addresses */
- UINT8 debugger_access; /* treat accesses as coming from the debugger */
- UINT8 log_unmap; /* log unmapped accesses in this space? */
- address_table read; /* memory read lookup table */
- address_table write; /* memory write lookup table */
+// ======================> address_space_config
+
+// describes an address space and provides basic functions to map addresses to bytes
+class address_space_config
+{
+public:
+ // construction/destruction
+ address_space_config();
+ address_space_config(const char *name, endianness_t endian, UINT8 datawidth, UINT8 addrwidth, INT8 addrshift = 0, address_map_constructor internal = NULL, address_map_constructor defmap = NULL);
+ address_space_config(const char *name, endianness_t endian, UINT8 datawidth, UINT8 addrwidth, INT8 addrshift, UINT8 logwidth, UINT8 pageshift, address_map_constructor internal = NULL, address_map_constructor defmap = NULL);
+
+ // getters
+ const char *name() const { return m_name; }
+ endianness_t endianness() const { return m_endianness; }
+ int data_width() const { return m_databus_width; }
+ int addr_width() const { return m_addrbus_width; }
+
+ // address-to-byte conversion helpers
+ inline offs_t addr2byte(offs_t address) const { return (m_addrbus_shift < 0) ? (address << -m_addrbus_shift) : (address >> m_addrbus_shift); }
+ inline offs_t addr2byte_end(offs_t address) const { return (m_addrbus_shift < 0) ? ((address << -m_addrbus_shift) | ((1 << -m_addrbus_shift) - 1)) : (address >> m_addrbus_shift); }
+ inline offs_t byte2addr(offs_t address) const { return (m_addrbus_shift > 0) ? (address << m_addrbus_shift) : (address >> -m_addrbus_shift); }
+ inline offs_t byte2addr_end(offs_t address) const { return (m_addrbus_shift > 0) ? ((address << m_addrbus_shift) | ((1 << -m_addrbus_shift) - 1)) : (address >> -m_addrbus_shift); }
+
+ // state
+ const char * m_name;
+ endianness_t m_endianness;
+ UINT8 m_databus_width;
+ UINT8 m_addrbus_width;
+ INT8 m_addrbus_shift;
+ UINT8 m_logaddr_width;
+ UINT8 m_page_shift;
+ address_map_constructor m_internal_map;
+ address_map_constructor m_default_map;
};
+// ======================> address_space
+
+// address_space holds live information about an address space
+class address_space : public bindable_object
+{
+ friend class address_table;
+ friend class address_table_read;
+ friend class address_table_write;
+ friend class direct_read_data;
+ friend class simple_list<address_space>;
+ friend resource_pool_object<address_space>::~resource_pool_object();
+
+protected:
+ // construction/destruction
+ address_space(device_memory_interface &memory, int spacenum, bool large);
+ ~address_space();
+
+public:
+ // public allocator
+ static address_space &allocate(running_machine &machine, const address_space_config &config, device_memory_interface &memory, int spacenum);
+
+ // getters
+ address_space *next() const { return m_next; }
+ device_t &device() const { return m_device; }
+ const char *name() const { return m_name; }
+ int spacenum() const { return m_spacenum; }
+ address_map *map() const { return m_map; }
+
+ direct_read_data &direct() const { return const_cast<direct_read_data &>(m_direct); }
+
+ int data_width() const { return m_config.data_width(); }
+ int addr_width() const { return m_config.addr_width(); }
+ endianness_t endianness() const { return m_config.endianness(); }
+ UINT64 unmap() const { return m_unmap; }
+
+ offs_t addrmask() const { return m_addrmask; }
+ offs_t bytemask() const { return m_bytemask; }
+ UINT8 addrchars() const { return m_addrchars; }
+ offs_t logaddrmask() const { return m_logaddrmask; }
+ offs_t logbytemask() const { return m_logbytemask; }
+ UINT8 logaddrchars() const { return m_logaddrchars; }
+
+ // debug helpers
+ const char *get_handler_string(read_or_write readorwrite, offs_t byteaddress);
+ bool debugger_access() const { return m_debugger_access; }
+ void set_debugger_access(bool debugger) { m_debugger_access = debugger; }
+ bool log_unmap() const { return m_log_unmap; }
+ void set_log_unmap(bool log) { m_log_unmap = log; }
+ void dump_map(FILE *file, read_or_write readorwrite);
+
+ // watchpoint enablers
+ virtual void enable_read_watchpoints(bool enable = true) = 0;
+ virtual void enable_write_watchpoints(bool enable = true) = 0;
+
+ // general accessors
+ virtual void accessors(data_accessors &accessors) const = 0;
+ virtual void *get_read_ptr(offs_t byteaddress) = 0;
+ virtual void *get_write_ptr(offs_t byteaddress) = 0;
+
+ // read accessors
+ virtual UINT8 read_byte(offs_t byteaddress) = 0;
+ virtual UINT16 read_word(offs_t byteaddress, UINT16 mask = 0xffff) = 0;
+ virtual UINT32 read_dword(offs_t byteaddress, UINT32 mask = 0xffffffff) = 0;
+ virtual UINT64 read_qword(offs_t byteaddress, UINT64 mask = U64(0xffffffffffffffff)) = 0;
+
+ // write accessors
+ virtual void write_byte(offs_t byteaddress, UINT8 data) = 0;
+ virtual void write_word(offs_t byteaddress, UINT16 data, UINT16 mask = 0xffff) = 0;
+ virtual void write_dword(offs_t byteaddress, UINT32 data, UINT32 mask = 0xffffffff) = 0;
+ virtual void write_qword(offs_t byteaddress, UINT64 data, UINT64 mask = U64(0xffffffffffffffff)) = 0;
+
+ // address-to-byte conversion helpers
+ offs_t address_to_byte(offs_t address) const { return m_config.addr2byte(address); }
+ offs_t address_to_byte_end(offs_t address) const { return m_config.addr2byte_end(address); }
+ offs_t byte_to_address(offs_t address) const { return m_config.byte2addr(address); }
+ offs_t byte_to_address_end(offs_t address) const { return m_config.byte2addr_end(address); }
+
+ // decryption
+ void set_decrypted_region(offs_t addrstart, offs_t addrend, void *base);
+
+ // direct access
+ direct_update_delegate set_direct_update_handler(direct_update_delegate function) { return m_direct.set_direct_update(function); }
+ bool set_direct_region(offs_t &byteaddress);
+
+ // static handler installation
+ void unmap(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read_or_write readorwrite, bool quiet);
+ void install_port(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, const char *rtag, const char *wtag);
+ void install_bank(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, const char *rtag, const char *wtag);
+ void *install_ram(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read_or_write readorwrite, void *baseptr = NULL);
+
+ // install new-style delegate handlers
+ UINT8 *install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_delegate rhandler, UINT64 unitmask = 0);
+ UINT8 *install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write8_delegate whandler, UINT64 unitmask = 0);
+ UINT8 *install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_delegate rhandler, write8_delegate whandler, UINT64 unitmask = 0);
+ UINT16 *install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_delegate rhandler, UINT64 unitmask = 0);
+ UINT16 *install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write16_delegate whandler, UINT64 unitmask = 0);
+ UINT16 *install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_delegate rhandler, write16_delegate whandler, UINT64 unitmask = 0);
+ UINT32 *install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_delegate rhandler, UINT64 unitmask = 0);
+ UINT32 *install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write32_delegate whandler, UINT64 unitmask = 0);
+ UINT32 *install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_delegate rhandler, write32_delegate whandler, UINT64 unitmask = 0);
+ UINT64 *install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_delegate rhandler, UINT64 unitmask = 0);
+ UINT64 *install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write64_delegate whandler, UINT64 unitmask = 0);
+ UINT64 *install_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_delegate rhandler, write64_delegate whandler, UINT64 unitmask = 0);
+
+ // install legacy address space handlers
+ UINT8 *install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_space_func rhandler, const char *rname, UINT64 unitmask = 0);
+ UINT8 *install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write8_space_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT8 *install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_space_func rhandler, const char *rname, write8_space_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT16 *install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_space_func rhandler, const char *rname, UINT64 unitmask = 0);
+ UINT16 *install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write16_space_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT16 *install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_space_func rhandler, const char *rname, write16_space_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT32 *install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_space_func rhandler, const char *rname, UINT64 unitmask = 0);
+ UINT32 *install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write32_space_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT32 *install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_space_func rhandler, const char *rname, write32_space_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT64 *install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_space_func rhandler, const char *rname, UINT64 unitmask = 0);
+ UINT64 *install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write64_space_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT64 *install_legacy_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_space_func rhandler, const char *rname, write64_space_func whandler, const char *wname, UINT64 unitmask = 0);
+
+ // install legacy device handlers
+ UINT8 *install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_device_func rhandler, const char *rname, UINT64 unitmask = 0);
+ UINT8 *install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write8_device_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT8 *install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_device_func rhandler, const char *rname, write8_device_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT16 *install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_device_func rhandler, const char *rname, UINT64 unitmask = 0);
+ UINT16 *install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write16_device_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT16 *install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_device_func rhandler, const char *rname, write16_device_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT32 *install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_device_func rhandler, const char *rname, UINT64 unitmask = 0);
+ UINT32 *install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write32_device_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT32 *install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_device_func rhandler, const char *rname, write32_device_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT64 *install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_device_func rhandler, const char *rname, UINT64 unitmask = 0);
+ UINT64 *install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write64_device_func whandler, const char *wname, UINT64 unitmask = 0);
+ UINT64 *install_legacy_handler(device_t &device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_device_func rhandler, const char *rname, write64_device_func whandler, const char *wname, UINT64 unitmask = 0);
+
+ // setup
+ void prepare_map();
+ void populate_from_map();
+ void allocate_memory();
+ void locate_memory();
+
+private:
+ // internal helpers
+ virtual address_table_read &read() = 0;
+ virtual address_table_write &write() = 0;
+ void populate_map_entry(const address_map_entry &entry, read_or_write readorwrite);
+ void bind_and_install_handler(const address_map_entry &entry, read_or_write readorwrite, device_t *device);
+ void adjust_addresses(offs_t &start, offs_t &end, offs_t &mask, offs_t &mirror);
+ void *find_backing_memory(offs_t addrstart, offs_t addrend);
+ bool needs_backing_store(const address_map_entry *entry);
+ memory_bank &bank_find_or_allocate(const char *tag, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read_or_write readorwrite);
+ address_map_entry *block_assign_intersecting(offs_t bytestart, offs_t byteend, UINT8 *base);
+
+public:
+ // public state (eventually will go away)
+ running_machine * machine; // kept for backwards compatibility
+ device_t * cpu; // kept for backwards compatibility
+ running_machine & m_machine; // reference to the owning machine
+
+protected:
+ // private state
+ address_space * m_next; // next address space in the global list
+ const address_space_config &m_config; // configuration of this space
+ device_t & m_device; // reference to the owning device
+ address_map * m_map; // original memory map
+ offs_t m_addrmask; // physical address mask
+ offs_t m_bytemask; // byte-converted physical address mask
+ offs_t m_logaddrmask; // logical address mask
+ offs_t m_logbytemask; // byte-converted logical address mask
+ UINT64 m_unmap; // unmapped value
+ UINT8 m_spacenum; // address space index
+ bool m_debugger_access; // treat accesses as coming from the debugger
+ bool m_log_unmap; // log unmapped accesses in this space?
+ direct_read_data & m_direct; // fast direct-access read info
+ const char * m_name; // friendly name of the address space
+ UINT8 m_addrchars; // number of characters to use for physical addresses
+ UINT8 m_logaddrchars; // number of characters to use for logical addresses
+};
+
-/***************************************************************************
- MACROS
-***************************************************************************/
-/* opcode base adjustment handler function macro */
-#define DIRECT_UPDATE_HANDLER(name) offs_t name(ATTR_UNUSED const address_space *space, ATTR_UNUSED offs_t address, direct_read_data *direct)
+//**************************************************************************
+// MACROS
+//**************************************************************************
+// opcode base adjustment handler function macro
+#define DIRECT_UPDATE_MEMBER(name) offs_t name(ATTR_UNUSED direct_read_data &direct, ATTR_UNUSED offs_t address)
+#define DIRECT_UPDATE_HANDLER(name) offs_t name(ATTR_UNUSED running_machine *machine, ATTR_UNUSED direct_read_data &direct, ATTR_UNUSED offs_t address)
-/* space read/write handler function macros */
+
+// space read/write handler function macros
#define READ8_HANDLER(name) UINT8 name(ATTR_UNUSED const address_space *space, ATTR_UNUSED offs_t offset)
#define WRITE8_HANDLER(name) void name(ATTR_UNUSED const address_space *space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT8 data)
#define READ16_HANDLER(name) UINT16 name(ATTR_UNUSED const address_space *space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT16 mem_mask)
@@ -191,7 +521,7 @@ struct _address_space
#define WRITE64_HANDLER(name) void name(ATTR_UNUSED const address_space *space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT64 data, ATTR_UNUSED UINT64 mem_mask)
-/* device read/write handler function macros */
+// device read/write handler function macros
#define READ8_DEVICE_HANDLER(name) UINT8 name(ATTR_UNUSED device_t *device, ATTR_UNUSED offs_t offset)
#define WRITE8_DEVICE_HANDLER(name) void name(ATTR_UNUSED device_t *device, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT8 data)
#define READ16_DEVICE_HANDLER(name) UINT16 name(ATTR_UNUSED device_t *device, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT16 mem_mask)
@@ -202,7 +532,27 @@ struct _address_space
#define WRITE64_DEVICE_HANDLER(name) void name(ATTR_UNUSED device_t *device, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT64 data, ATTR_UNUSED UINT64 mem_mask)
-/* helper macro for merging data with the memory mask */
+// space read/write handler function macros
+#define READ8_MEMBER(name) UINT8 name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT8 mem_mask)
+#define WRITE8_MEMBER(name) void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT8 data, ATTR_UNUSED UINT8 mem_mask)
+#define READ16_MEMBER(name) UINT16 name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT16 mem_mask)
+#define WRITE16_MEMBER(name) void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT16 data, ATTR_UNUSED UINT16 mem_mask)
+#define READ32_MEMBER(name) UINT32 name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT32 mem_mask)
+#define WRITE32_MEMBER(name) void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT32 data, ATTR_UNUSED UINT32 mem_mask)
+#define READ64_MEMBER(name) UINT64 name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT64 mem_mask)
+#define WRITE64_MEMBER(name) void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT64 data, ATTR_UNUSED UINT64 mem_mask)
+
+#define DECLARE_READ8_MEMBER(name) UINT8 name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT8 mem_mask = 0xff)
+#define DECLARE_WRITE8_MEMBER(name) void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT8 data, ATTR_UNUSED UINT8 mem_mask = 0xff)
+#define DECLARE_READ16_MEMBER(name) UINT16 name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT16 mem_mask = 0xffff)
+#define DECLARE_WRITE16_MEMBER(name) void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT16 data, ATTR_UNUSED UINT16 mem_mask = 0xffff)
+#define DECLARE_READ32_MEMBER(name) UINT32 name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT32 mem_mask = 0xffffffff)
+#define DECLARE_WRITE32_MEMBER(name) void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT32 data, ATTR_UNUSED UINT32 mem_mask = 0xffffffff)
+#define DECLARE_READ64_MEMBER(name) UINT64 name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT64 mem_mask = U64(0xffffffffffffffff))
+#define DECLARE_WRITE64_MEMBER(name) void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT64 data, ATTR_UNUSED UINT64 mem_mask = U64(0xffffffffffffffff))
+
+
+// helper macro for merging data with the memory mask
#define COMBINE_DATA(varptr) (*(varptr) = (*(varptr) & ~mem_mask) | (data & mem_mask))
#define ACCESSING_BITS_0_7 ((mem_mask & 0x000000ff) != 0)
@@ -223,342 +573,304 @@ struct _address_space
#define ACCESSING_BITS_32_63 ((mem_mask & U64(0xffffffff00000000)) != 0)
-/* opcode range safety check */
-#define memory_address_outside_direct_region(S,A) ((UNEXPECTED((A) < (S)->direct.bytestart) || UNEXPECTED((A) > (S)->direct.byteend)))
+// macros for accessing bytes and words within larger chunks
+
+// read/write a byte to a 16-bit space
+#define BYTE_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0))
+#define BYTE_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,1))
+
+// read/write a byte to a 32-bit space
+#define BYTE4_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(3,0))
+#define BYTE4_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,3))
+
+// read/write a word to a 32-bit space
+#define WORD_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(2,0))
+#define WORD_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,2))
+
+// read/write a byte to a 64-bit space
+#define BYTE8_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(7,0))
+#define BYTE8_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,7))
+
+// read/write a word to a 64-bit space
+#define WORD2_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(6,0))
+#define WORD2_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,6))
+
+// read/write a dword to a 64-bit space
+#define DWORD_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(4,0))
+#define DWORD_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,4))
-/* wrappers for dynamic read handler installation */
+// wrappers for dynamic read handler installation
#define memory_install_read8_handler(space, start, end, mask, mirror, rhandler) \
- _memory_install_handler8(space, start, end, mask, mirror, rhandler, #rhandler, NULL, NULL, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(start, end, mask, mirror, rhandler, #rhandler)
#define memory_install_read16_handler(space, start, end, mask, mirror, rhandler) \
- _memory_install_handler16(space, start, end, mask, mirror, rhandler, #rhandler, NULL, NULL, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(start, end, mask, mirror, rhandler, #rhandler)
#define memory_install_read32_handler(space, start, end, mask, mirror, rhandler) \
- _memory_install_handler32(space, start, end, mask, mirror, rhandler, #rhandler, NULL, NULL, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(start, end, mask, mirror, rhandler, #rhandler)
#define memory_install_read64_handler(space, start, end, mask, mirror, rhandler) \
- _memory_install_handler64(space, start, end, mask, mirror, rhandler, #rhandler, NULL, NULL, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(start, end, mask, mirror, rhandler, #rhandler)
#define memory_install_read8_device_handler(space, device, start, end, mask, mirror, rhandler) \
- _memory_install_device_handler8(space, device, start, end, mask, mirror, rhandler, #rhandler, NULL, NULL, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(*(device), start, end, mask, mirror, rhandler, #rhandler)
#define memory_install_read16_device_handler(space, device, start, end, mask, mirror, rhandler) \
- _memory_install_device_handler16(space, device, start, end, mask, mirror, rhandler, #rhandler, NULL, NULL, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(*(device), start, end, mask, mirror, rhandler, #rhandler)
#define memory_install_read32_device_handler(space, device, start, end, mask, mirror, rhandler) \
- _memory_install_device_handler32(space, device, start, end, mask, mirror, rhandler, #rhandler, NULL, NULL, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(*(device), start, end, mask, mirror, rhandler, #rhandler)
#define memory_install_read64_device_handler(space, device, start, end, mask, mirror, rhandler) \
- _memory_install_device_handler64(space, device, start, end, mask, mirror, rhandler, #rhandler, NULL, NULL, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(*(device), start, end, mask, mirror, rhandler, #rhandler)
#define memory_install_read_port(space, start, end, mask, mirror, rtag) \
- _memory_install_port(space, start, end, mask, mirror, rtag, NULL)
+ const_cast<address_space *>(space)->install_port(start, end, mask, mirror, rtag, NULL)
#define memory_install_read_bank(space, start, end, mask, mirror, rtag) \
- _memory_install_bank(space, start, end, mask, mirror, rtag, NULL)
+ const_cast<address_space *>(space)->install_bank(start, end, mask, mirror, rtag, NULL)
#define memory_install_rom(space, start, end, mask, mirror, baseptr) \
- _memory_install_ram(space, start, end, mask, mirror, TRUE, FALSE, baseptr)
+ const_cast<address_space *>(space)->install_ram(start, end, mask, mirror, ROW_READ, baseptr)
#define memory_unmap_read(space, start, end, mask, mirror) \
- _memory_unmap(space, start, end, mask, mirror, TRUE, FALSE, FALSE)
+ const_cast<address_space *>(space)->unmap(start, end, mask, mirror, ROW_READ, false)
#define memory_nop_read(space, start, end, mask, mirror) \
- _memory_unmap(space, start, end, mask, mirror, TRUE, FALSE, TRUE)
+ const_cast<address_space *>(space)->unmap(start, end, mask, mirror, ROW_READ, true)
-/* wrappers for dynamic write handler installation */
+// wrappers for dynamic write handler installation
#define memory_install_write8_handler(space, start, end, mask, mirror, whandler) \
- _memory_install_handler8(space, start, end, mask, mirror, NULL, NULL, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(start, end, mask, mirror, whandler, #whandler)
#define memory_install_write16_handler(space, start, end, mask, mirror, whandler) \
- _memory_install_handler16(space, start, end, mask, mirror, NULL, NULL, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(start, end, mask, mirror, whandler, #whandler)
#define memory_install_write32_handler(space, start, end, mask, mirror, whandler) \
- _memory_install_handler32(space, start, end, mask, mirror, NULL, NULL, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(start, end, mask, mirror, whandler, #whandler)
#define memory_install_write64_handler(space, start, end, mask, mirror, whandler) \
- _memory_install_handler64(space, start, end, mask, mirror, NULL, NULL, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(start, end, mask, mirror, whandler, #whandler)
#define memory_install_write8_device_handler(space, device, start, end, mask, mirror, whandler) \
- _memory_install_device_handler8(space, device, start, end, mask, mirror, NULL, NULL, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(*(device), start, end, mask, mirror, whandler, #whandler)
#define memory_install_write16_device_handler(space, device, start, end, mask, mirror, whandler) \
- _memory_install_device_handler16(space, device, start, end, mask, mirror, NULL, NULL, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(*(device), start, end, mask, mirror, whandler, #whandler)
#define memory_install_write32_device_handler(space, device, start, end, mask, mirror, whandler) \
- _memory_install_device_handler32(space, device, start, end, mask, mirror, NULL, NULL, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(*(device), start, end, mask, mirror, whandler, #whandler)
#define memory_install_write64_device_handler(space, device, start, end, mask, mirror, whandler) \
- _memory_install_device_handler64(space, device, start, end, mask, mirror, NULL, NULL, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(*(device), start, end, mask, mirror, whandler, #whandler)
#define memory_install_write_port(space, start, end, mask, mirror, wtag) \
- _memory_install_port(space, start, end, mask, mirror, NULL, wtag)
+ const_cast<address_space *>(space)->install_port(start, end, mask, mirror, NULL, wtag)
#define memory_install_write_bank(space, start, end, mask, mirror, wtag) \
- _memory_install_bank(space, start, end, mask, mirror, NULL, wtag)
+ const_cast<address_space *>(space)->install_bank(start, end, mask, mirror, NULL, wtag)
#define memory_install_writeonly(space, start, end, mask, mirror, baseptr) \
- _memory_install_ram(space, start, end, mask, mirror, FALSE, TRUE, baseptr)
+ const_cast<address_space *>(space)->install_ram(start, end, mask, mirror, ROW_WRITE, baseptr)
#define memory_unmap_write(space, start, end, mask, mirror) \
- _memory_unmap(space, start, end, mask, mirror, FALSE, TRUE, FALSE)
+ const_cast<address_space *>(space)->unmap(start, end, mask, mirror, ROW_WRITE, false)
#define memory_nop_write(space, start, end, mask, mirror) \
- _memory_unmap(space, start, end, mask, mirror, FALSE, TRUE, TRUE)
+ const_cast<address_space *>(space)->unmap(start, end, mask, mirror, ROW_WRITE, true)
-/* wrappers for dynamic read/write handler installation */
+// wrappers for dynamic read/write handler installation
#define memory_install_readwrite8_handler(space, start, end, mask, mirror, rhandler, whandler) \
- _memory_install_handler8(space, start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler)
#define memory_install_readwrite16_handler(space, start, end, mask, mirror, rhandler, whandler) \
- _memory_install_handler16(space, start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler)
#define memory_install_readwrite32_handler(space, start, end, mask, mirror, rhandler, whandler) \
- _memory_install_handler32(space, start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler)
#define memory_install_readwrite64_handler(space, start, end, mask, mirror, rhandler, whandler) \
- _memory_install_handler64(space, start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler)
#define memory_install_readwrite8_device_handler(space, device, start, end, mask, mirror, rhandler, whandler) \
- _memory_install_device_handler8(space, device, start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(*(device), start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler)
#define memory_install_readwrite16_device_handler(space, device, start, end, mask, mirror, rhandler, whandler) \
- _memory_install_device_handler16(space, device, start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(*(device), start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler)
#define memory_install_readwrite32_device_handler(space, device, start, end, mask, mirror, rhandler, whandler) \
- _memory_install_device_handler32(space, device, start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(*(device), start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler)
#define memory_install_readwrite64_device_handler(space, device, start, end, mask, mirror, rhandler, whandler) \
- _memory_install_device_handler64(space, device, start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler, 0)
+ const_cast<address_space *>(space)->install_legacy_handler(*(device), start, end, mask, mirror, rhandler, #rhandler, whandler, #whandler)
#define memory_install_readwrite_port(space, start, end, mask, mirror, rtag, wtag) \
- _memory_install_port(space, start, end, mask, mirror, rtag, wtag)
+ const_cast<address_space *>(space)->install_port(start, end, mask, mirror, rtag, wtag)
#define memory_install_readwrite_bank(space, start, end, mask, mirror, tag) \
- _memory_install_bank(space, start, end, mask, mirror, tag, tag)
+ const_cast<address_space *>(space)->install_bank(start, end, mask, mirror, tag, tag)
#define memory_install_ram(space, start, end, mask, mirror, baseptr) \
- _memory_install_ram(space, start, end, mask, mirror, TRUE, TRUE, baseptr)
+ const_cast<address_space *>(space)->install_ram(start, end, mask, mirror, ROW_READWRITE, baseptr)
#define memory_unmap_readwrite(space, start, end, mask, mirror) \
- _memory_unmap(space, start, end, mask, mirror, TRUE, TRUE, FALSE)
+ const_cast<address_space *>(space)->unmap(start, end, mask, mirror, ROW_READWRITE, false)
#define memory_nop_readwrite(space, start, end, mask, mirror) \
- _memory_unmap(space, start, end, mask, mirror, TRUE, TRUE, TRUE)
+ const_cast<address_space *>(space)->unmap(start, end, mask, mirror, ROW_READWRITE, true)
-/* macros for accessing bytes and words within larger chunks */
-/* read/write a byte to a 16-bit space */
-#define BYTE_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0))
-#define BYTE_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,1))
-
-/* read/write a byte to a 32-bit space */
-#define BYTE4_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(3,0))
-#define BYTE4_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,3))
-
-/* read/write a word to a 32-bit space */
-#define WORD_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(2,0))
-#define WORD_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,2))
-
-/* read/write a byte to a 64-bit space */
-#define BYTE8_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(7,0))
-#define BYTE8_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,7))
-
-/* read/write a word to a 64-bit space */
-#define WORD2_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(6,0))
-#define WORD2_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,6))
-
-/* read/write a dword to a 64-bit space */
-#define DWORD_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(4,0))
-#define DWORD_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,4))
-
-
-
-/***************************************************************************
- GLOBAL VARIABLES
-***************************************************************************/
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
extern const char *const address_space_names[ADDRESS_SPACES];
-/***************************************************************************
- FUNCTION PROTOTYPES FOR CORE MEMORY FUNCTIONS
-***************************************************************************/
-
-
-/* ----- core system operations ----- */
+//**************************************************************************
+// FUNCTION PROTOTYPES FOR CORE MEMORY FUNCTIONS
+//**************************************************************************
-/* initialize the memory system */
+// initialize the memory system
void memory_init(running_machine *machine);
-
-
-/* ----- direct access control ----- */
-
-/* registers an address range as having a decrypted data pointer */
-void memory_set_decrypted_region(const address_space *space, offs_t addrstart, offs_t addrend, void *base) ATTR_NONNULL(1, 4);
-
-/* register a handler for opcode base changes on a given device */
-direct_update_func memory_set_direct_update_handler(const address_space *space, direct_update_func function) ATTR_NONNULL(1);
-
-/* called by device cores to update the opcode base for the given address */
-int memory_set_direct_region(const address_space *space, offs_t *byteaddress) ATTR_NONNULL(1, 2);
-
-/* return a pointer the memory byte provided in the given address space, or NULL if it is not mapped to a bank */
-void *memory_get_read_ptr(const address_space *space, offs_t byteaddress) ATTR_NONNULL(1);
-
-/* return a pointer the memory byte provided in the given address space, or NULL if it is not mapped to a writeable bank */
-void *memory_get_write_ptr(const address_space *space, offs_t byteaddress) ATTR_NONNULL(1);
-
-
-
-/* ----- memory banking ----- */
-
-/* configure the addresses for a bank */
+// configure the addresses for a bank
void memory_configure_bank(running_machine *machine, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(1, 5);
-/* configure the decrypted addresses for a bank */
+// configure the decrypted addresses for a bank
void memory_configure_bank_decrypted(running_machine *machine, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(1, 5);
-/* select one pre-configured entry to be the new bank base */
+// select one pre-configured entry to be the new bank base
void memory_set_bank(running_machine *machine, const char *tag, int entrynum) ATTR_NONNULL(1);
-/* return the currently selected bank */
+// return the currently selected bank
int memory_get_bank(running_machine *machine, const char *tag) ATTR_NONNULL(1);
-/* set the absolute address of a bank base */
+// set the absolute address of a bank base
void memory_set_bankptr(running_machine *machine, const char *tag, void *base) ATTR_NONNULL(1, 3);
+// dump the internal memory tables to the given file
+void memory_dump(running_machine *machine, FILE *file);
-/* ----- dynamic address space mapping ----- */
-
-/* install a new 8-bit memory handler into the given address space, returning a pointer to the memory backing it, if present */
-UINT8 *_memory_install_handler8(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_space_func rhandler, const char *rhandler_name, write8_space_func whandler, const char *whandler_name, int handlerunitmask) ATTR_NONNULL(1);
-
-/* same as above but explicitly for 16-bit handlers */
-UINT16 *_memory_install_handler16(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_space_func rhandler, const char *rhandler_name, write16_space_func whandler, const char *whandler_name, int handlerunitmask) ATTR_NONNULL(1);
-
-/* same as above but explicitly for 32-bit handlers */
-UINT32 *_memory_install_handler32(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_space_func rhandler, const char *rhandler_name, write32_space_func whandler, const char *whandler_name, int handlerunitmask) ATTR_NONNULL(1);
-
-/* same as above but explicitly for 64-bit handlers */
-UINT64 *_memory_install_handler64(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_space_func rhandler, const char *rhandler_name, write64_space_func whandler, const char *whandler_name, int handlerunitmask) ATTR_NONNULL(1);
-
-/* install a new 8-bit device memory handler into the given address space, returning a pointer to the memory backing it, if present */
-UINT8 *_memory_install_device_handler8(const address_space *space, device_t *device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_device_func rhandler, const char *rhandler_name, write8_device_func whandler, const char *whandler_name, int handlerunitmask) ATTR_NONNULL(1, 2);
-
-/* same as above but explicitly for 16-bit handlers */
-UINT16 *_memory_install_device_handler16(const address_space *space, device_t *device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_device_func rhandler, const char *rhandler_name, write16_device_func whandler, const char *whandler_name, int handlerunitmask) ATTR_NONNULL(1, 2);
-
-/* same as above but explicitly for 32-bit handlers */
-UINT32 *_memory_install_device_handler32(const address_space *space, device_t *device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_device_func rhandler, const char *rhandler_name, write32_device_func whandler, const char *whandler_name, int handlerunitmask) ATTR_NONNULL(1, 2);
-
-/* same as above but explicitly for 64-bit handlers */
-UINT64 *_memory_install_device_handler64(const address_space *space, device_t *device, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_device_func rhandler, const char *rhandler_name, write64_device_func whandler, const char *whandler_name, int handlerunitmask) ATTR_NONNULL(1, 2);
-
-/* install a new port into the given address space */
-void _memory_install_port(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, const char *rtag, const char *wtag) ATTR_NONNULL(1);
-
-/* install a new bank into the given address space */
-void _memory_install_bank(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, const char *rtag, const char *wtag) ATTR_NONNULL(1);
-
-/* install a simple fixed RAM region into the given address space */
-void *_memory_install_ram(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, UINT8 install_read, UINT8 install_write, void *baseptr) ATTR_NONNULL(1);
-
-/* unmap a section of address space */
-void _memory_unmap(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, UINT8 unmap_read, UINT8 unmap_write, UINT8 quiet) ATTR_NONNULL(1);
-
-
-
-/* ----- debugger helpers ----- */
-
-/* return a string describing the handler at a particular offset */
-const char *memory_get_handler_string(const address_space *space, int read0_or_write1, offs_t byteaddress);
-
-/* enable/disable read watchpoint tracking for a given address space */
-void memory_enable_read_watchpoints(const address_space *space, int enable);
-
-/* enable/disable write watchpoint tracking for a given address space */
-void memory_enable_write_watchpoints(const address_space *space, int enable);
-
-/* control whether subsequent accesses are treated as coming from the debugger */
-void memory_set_debugger_access(const address_space *space, int debugger);
-
-/* sets whether unmapped memory accesses should be logged or not */
-void memory_set_log_unmap(const address_space *space, int log);
-/* gets whether unmapped memory accesses are being logged or not */
-int memory_get_log_unmap(const address_space *space);
+//**************************************************************************
+// INLINE FUNCTIONS
+//**************************************************************************
-/* dump the internal memory tables to the given file */
-void memory_dump(running_machine *machine, FILE *file);
+//-------------------------------------------------
+// read_raw_ptr - return a pointer to valid RAM
+// referenced by the address, or NULL if no RAM
+// backing that address
+//-------------------------------------------------
+inline void *direct_read_data::read_raw_ptr(offs_t byteaddress)
+{
+ if (address_is_valid(byteaddress))
+ return &m_raw[byteaddress & m_bytemask];
+ return NULL;
+}
+inline void *direct_read_data::read_decrypted_ptr(offs_t byteaddress)
+{
+ if (address_is_valid(byteaddress))
+ return &m_decrypted[byteaddress & m_bytemask];
+ return NULL;
+}
-/***************************************************************************
- INLINE FUNCTIONS
-***************************************************************************/
-/*-------------------------------------------------
- memory_address_to_byte - convert an address in
- the specified address space to a byte offset
--------------------------------------------------*/
+//-------------------------------------------------
+// read_raw_byte - read a byte via the
+// direct_read_data class
+//-------------------------------------------------
-INLINE offs_t memory_address_to_byte(const address_space *space, offs_t address)
+inline UINT8 direct_read_data::read_raw_byte(offs_t byteaddress)
{
- return (space->ashift < 0) ? (address << -space->ashift) : (address >> space->ashift);
+ if (address_is_valid(byteaddress))
+ return m_raw[byteaddress & m_bytemask];
+ return m_space.read_byte(byteaddress);
}
+
+inline UINT8 direct_read_data::read_decrypted_byte(offs_t byteaddress)
+{
+ if (address_is_valid(byteaddress))
+ return m_decrypted[byteaddress & m_bytemask];
+ return m_space.read_byte(byteaddress);
+}
+
+//-------------------------------------------------
+// read_raw_word - read a word via the
+// direct_read_data class
+//-------------------------------------------------
-/*-------------------------------------------------
- memory_address_to_byte_end - convert an address
- in the specified address space to a byte
- offset specifying the last byte covered by
- the address
--------------------------------------------------*/
-
-INLINE offs_t memory_address_to_byte_end(const address_space *space, offs_t address)
+inline UINT16 direct_read_data::read_raw_word(offs_t byteaddress)
{
- return (space->ashift < 0) ? ((address << -space->ashift) | ((1 << -space->ashift) - 1)) : (address >> space->ashift);
+ if (address_is_valid(byteaddress))
+ return *reinterpret_cast<UINT16 *>(&m_raw[byteaddress & m_bytemask]);
+ return m_space.read_word(byteaddress);
}
+
+inline UINT16 direct_read_data::read_decrypted_word(offs_t byteaddress)
+{
+ if (address_is_valid(byteaddress))
+ return *reinterpret_cast<UINT16 *>(&m_decrypted[byteaddress & m_bytemask]);
+ return m_space.read_word(byteaddress);
+}
+
+//-------------------------------------------------
+// read_raw_dword - read a dword via the
+// direct_read_data class
+//-------------------------------------------------
-/*-------------------------------------------------
- memory_byte_to_address - convert a byte offset
- to an address in the specified address space
--------------------------------------------------*/
-
-INLINE offs_t memory_byte_to_address(const address_space *space, offs_t address)
+inline UINT32 direct_read_data::read_raw_dword(offs_t byteaddress)
{
- return (space->ashift < 0) ? (address >> -space->ashift) : (address << space->ashift);
+ if (address_is_valid(byteaddress))
+ return *reinterpret_cast<UINT32 *>(&m_raw[byteaddress & m_bytemask]);
+ return m_space.read_dword(byteaddress);
}
+
+inline UINT32 direct_read_data::read_decrypted_dword(offs_t byteaddress)
+{
+ if (address_is_valid(byteaddress))
+ return *reinterpret_cast<UINT32 *>(&m_decrypted[byteaddress & m_bytemask]);
+ return m_space.read_dword(byteaddress);
+}
+
+//-------------------------------------------------
+// read_raw_qword - read a qword via the
+// direct_read_data class
+//-------------------------------------------------
-/*-------------------------------------------------
- memory_byte_to_address_end - convert a byte
- offset to an address in the specified address
- space specifying the last address covered by
- the byte
--------------------------------------------------*/
-
-INLINE offs_t memory_byte_to_address_end(const address_space *space, offs_t address)
+inline UINT64 direct_read_data::read_raw_qword(offs_t byteaddress)
+{
+ if (address_is_valid(byteaddress))
+ return *reinterpret_cast<UINT64 *>(&m_raw[byteaddress & m_bytemask]);
+ return m_space.read_qword(byteaddress);
+}
+
+inline UINT64 direct_read_data::read_decrypted_qword(offs_t byteaddress)
{
- return (space->ashift < 0) ? (address >> -space->ashift) : ((address << space->ashift) | ((1 << space->ashift) - 1));
+ if (address_is_valid(byteaddress))
+ return *reinterpret_cast<UINT64 *>(&m_decrypted[byteaddress & m_bytemask]);
+ return m_space.read_qword(byteaddress);
}
+
-/*-------------------------------------------------
- memory_read_byte/word/dword/qword - read a
- value from the specified address space
--------------------------------------------------*/
-INLINE UINT8 memory_read_byte(const address_space *space, offs_t byteaddress)
+//**************************************************************************
+// LEGACY FUNCTIONS TO REMOVE
+//**************************************************************************
+
+static inline UINT8 memory_read_byte(const address_space *space, offs_t byteaddress)
{
- return (*space->accessors.read_byte)(space, byteaddress);
+ return const_cast<address_space *>(space)->read_byte(byteaddress);
}
-INLINE UINT16 memory_read_word(const address_space *space, offs_t byteaddress)
+static inline UINT16 memory_read_word(const address_space *space, offs_t byteaddress)
{
- return (*space->accessors.read_word)(space, byteaddress);
+ return const_cast<address_space *>(space)->read_word(byteaddress);
}
-INLINE UINT16 memory_read_word_masked(const address_space *space, offs_t byteaddress, UINT16 mask)
+static inline UINT16 memory_read_word_masked(const address_space *space, offs_t byteaddress, UINT16 mask)
{
- return (*space->accessors.read_word_masked)(space, byteaddress, mask);
+ return const_cast<address_space *>(space)->read_word(byteaddress, mask);
}
-INLINE UINT32 memory_read_dword(const address_space *space, offs_t byteaddress)
+static inline UINT32 memory_read_dword(const address_space *space, offs_t byteaddress)
{
- return (*space->accessors.read_dword)(space, byteaddress);
+ return const_cast<address_space *>(space)->read_dword(byteaddress);
}
-INLINE UINT32 memory_read_dword_masked(const address_space *space, offs_t byteaddress, UINT32 mask)
+static inline UINT32 memory_read_dword_masked(const address_space *space, offs_t byteaddress, UINT32 mask)
{
- return (*space->accessors.read_dword_masked)(space, byteaddress, mask);
+ return const_cast<address_space *>(space)->read_dword(byteaddress, mask);
}
-INLINE UINT64 memory_read_qword(const address_space *space, offs_t byteaddress)
+static inline UINT64 memory_read_qword(const address_space *space, offs_t byteaddress)
{
- return (*space->accessors.read_qword)(space, byteaddress);
+ return const_cast<address_space *>(space)->read_qword(byteaddress);
}
-INLINE UINT64 memory_read_qword_masked(const address_space *space, offs_t byteaddress, UINT64 mask)
+static inline UINT64 memory_read_qword_masked(const address_space *space, offs_t byteaddress, UINT64 mask)
{
- return (*space->accessors.read_qword_masked)(space, byteaddress, mask);
+ return const_cast<address_space *>(space)->read_qword(byteaddress, mask);
}
@@ -567,252 +879,222 @@ INLINE UINT64 memory_read_qword_masked(const address_space *space, offs_t bytead
value to the specified address space
-------------------------------------------------*/
-INLINE void memory_write_byte(const address_space *space, offs_t byteaddress, UINT8 data)
+static inline void memory_write_byte(const address_space *space, offs_t byteaddress, UINT8 data)
{
- (*space->accessors.write_byte)(space, byteaddress, data);
+ const_cast<address_space *>(space)->write_byte(byteaddress, data);
}
-INLINE void memory_write_word(const address_space *space, offs_t byteaddress, UINT16 data)
+static inline void memory_write_word(const address_space *space, offs_t byteaddress, UINT16 data)
{
- (*space->accessors.write_word)(space, byteaddress, data);
+ const_cast<address_space *>(space)->write_word(byteaddress, data);
}
-INLINE void memory_write_word_masked(const address_space *space, offs_t byteaddress, UINT16 data, UINT16 mask)
+static inline void memory_write_word_masked(const address_space *space, offs_t byteaddress, UINT16 data, UINT16 mask)
{
- (*space->accessors.write_word_masked)(space, byteaddress, data, mask);
+ const_cast<address_space *>(space)->write_word(byteaddress, data, mask);
}
-INLINE void memory_write_dword(const address_space *space, offs_t byteaddress, UINT32 data)
+static inline void memory_write_dword(const address_space *space, offs_t byteaddress, UINT32 data)
{
- (*space->accessors.write_dword)(space, byteaddress, data);
+ const_cast<address_space *>(space)->write_dword(byteaddress, data);
}
-INLINE void memory_write_dword_masked(const address_space *space, offs_t byteaddress, UINT32 data, UINT32 mask)
+static inline void memory_write_dword_masked(const address_space *space, offs_t byteaddress, UINT32 data, UINT32 mask)
{
- (*space->accessors.write_dword_masked)(space, byteaddress, data, mask);
+ const_cast<address_space *>(space)->write_dword(byteaddress, data, mask);
}
-INLINE void memory_write_qword(const address_space *space, offs_t byteaddress, UINT64 data)
+static inline void memory_write_qword(const address_space *space, offs_t byteaddress, UINT64 data)
{
- (*space->accessors.write_qword)(space, byteaddress, data);
+ const_cast<address_space *>(space)->write_qword(byteaddress, data);
}
-INLINE void memory_write_qword_masked(const address_space *space, offs_t byteaddress, UINT64 data, UINT64 mask)
+static inline void memory_write_qword_masked(const address_space *space, offs_t byteaddress, UINT64 data, UINT64 mask)
{
- (*space->accessors.write_qword_masked)(space, byteaddress, data, mask);
+ const_cast<address_space *>(space)->write_qword(byteaddress, data, mask);
}
-/*-------------------------------------------------
- memory_decrypted_read_byte/word/dword/qword -
- read a value from the specified address space
- using the direct addressing mechanism and
- the decrypted base pointer
--------------------------------------------------*/
+static inline void *memory_raw_read_ptr(const address_space *space, offs_t byteaddress) { return space->direct().read_raw_ptr(byteaddress); }
+static inline UINT8 memory_raw_read_byte(const address_space *space, offs_t byteaddress) { return space->direct().read_raw_byte(byteaddress); }
+static inline UINT16 memory_raw_read_word(const address_space *space, offs_t byteaddress) { return space->direct().read_raw_word(byteaddress); }
+static inline UINT32 memory_raw_read_dword(const address_space *space, offs_t byteaddress) { return space->direct().read_raw_dword(byteaddress); }
+static inline UINT64 memory_raw_read_qword(const address_space *space, offs_t byteaddress) { return space->direct().read_raw_qword(byteaddress); }
+
+static inline void *memory_decrypted_read_ptr(const address_space *space, offs_t byteaddress) { return space->direct().read_decrypted_ptr(byteaddress); }
+static inline UINT8 memory_decrypted_read_byte(const address_space *space, offs_t byteaddress) { return space->direct().read_decrypted_byte(byteaddress); }
+static inline UINT16 memory_decrypted_read_word(const address_space *space, offs_t byteaddress) { return space->direct().read_decrypted_word(byteaddress); }
+static inline UINT32 memory_decrypted_read_dword(const address_space *space, offs_t byteaddress) { return space->direct().read_decrypted_dword(byteaddress); }
+static inline UINT64 memory_decrypted_read_qword(const address_space *space, offs_t byteaddress) { return space->direct().read_decrypted_qword(byteaddress); }
+
-INLINE void *memory_decrypted_read_ptr(const address_space *space, offs_t byteaddress)
-{
- if (!memory_address_outside_direct_region(space, byteaddress) || memory_set_direct_region(space, &byteaddress))
- return &space->direct.decrypted[byteaddress & space->direct.bytemask];
- return NULL;
-}
-INLINE UINT8 memory_decrypted_read_byte(const address_space *space, offs_t byteaddress)
+
+static inline void memory_set_decrypted_region(const address_space *space, offs_t addrstart, offs_t addrend, void *base)
{
- if (!memory_address_outside_direct_region(space, byteaddress) || memory_set_direct_region(space, &byteaddress))
- return space->direct.decrypted[byteaddress & space->direct.bytemask];
- return memory_read_byte(space, byteaddress);
+ const_cast<address_space *>(space)->set_decrypted_region(addrstart, addrend, base);
}
-INLINE UINT16 memory_decrypted_read_word(const address_space *space, offs_t byteaddress)
+static inline void *memory_get_read_ptr(const address_space *space, offs_t byteaddress)
{
- if (!memory_address_outside_direct_region(space, byteaddress) || memory_set_direct_region(space, &byteaddress))
- return *(UINT16 *)&space->direct.decrypted[byteaddress & space->direct.bytemask];
- return memory_read_word(space, byteaddress);
+ return const_cast<address_space *>(space)->get_read_ptr(byteaddress);
}
-INLINE UINT32 memory_decrypted_read_dword(const address_space *space, offs_t byteaddress)
+static inline void *memory_get_write_ptr(const address_space *space, offs_t byteaddress)
{
- if (!memory_address_outside_direct_region(space, byteaddress) || memory_set_direct_region(space, &byteaddress))
- return *(UINT32 *)&space->direct.decrypted[byteaddress & space->direct.bytemask];
- return memory_read_dword(space, byteaddress);
+ return const_cast<address_space *>(space)->get_write_ptr(byteaddress);
}
-INLINE UINT64 memory_decrypted_read_qword(const address_space *space, offs_t byteaddress)
+static inline const char *memory_get_handler_string(const address_space *space, read_or_write readorwrite, offs_t byteaddress)
{
- if (!memory_address_outside_direct_region(space, byteaddress) || memory_set_direct_region(space, &byteaddress))
- return *(UINT64 *)&space->direct.decrypted[byteaddress & space->direct.bytemask];
- return memory_read_qword(space, byteaddress);
+ return const_cast<address_space *>(space)->get_handler_string(readorwrite, byteaddress);
}
-
-/*-------------------------------------------------
- memory_raw_read_byte/word/dword/qword -
- read a value from the specified address space
- using the direct addressing mechanism and
- the raw base pointer
--------------------------------------------------*/
-
-INLINE void *memory_raw_read_ptr(const address_space *space, offs_t byteaddress)
+static inline void memory_enable_read_watchpoints(const address_space *space, bool enable)
{
- if (!memory_address_outside_direct_region(space, byteaddress) || memory_set_direct_region(space, &byteaddress))
- return &space->direct.raw[byteaddress & space->direct.bytemask];
- return NULL;
+ const_cast<address_space *>(space)->enable_read_watchpoints(enable);
}
-INLINE UINT8 memory_raw_read_byte(const address_space *space, offs_t byteaddress)
+static inline void memory_enable_write_watchpoints(const address_space *space, bool enable)
{
- if (!memory_address_outside_direct_region(space, byteaddress) || memory_set_direct_region(space, &byteaddress))
- return space->direct.raw[byteaddress & space->direct.bytemask];
- return memory_read_byte(space, byteaddress);
+ const_cast<address_space *>(space)->enable_write_watchpoints(enable);
}
-INLINE UINT16 memory_raw_read_word(const address_space *space, offs_t byteaddress)
+static inline void memory_set_debugger_access(const address_space *space, bool debugger)
{
- if (!memory_address_outside_direct_region(space, byteaddress) || memory_set_direct_region(space, &byteaddress))
- return *(UINT16 *)&space->direct.raw[byteaddress & space->direct.bytemask];
- return memory_read_word(space, byteaddress);
+ const_cast<address_space *>(space)->set_debugger_access(debugger);
}
-INLINE UINT32 memory_raw_read_dword(const address_space *space, offs_t byteaddress)
+static inline void memory_set_log_unmap(const address_space *space, bool log)
{
- if (!memory_address_outside_direct_region(space, byteaddress) || memory_set_direct_region(space, &byteaddress))
- return *(UINT32 *)&space->direct.raw[byteaddress & space->direct.bytemask];
- return memory_read_dword(space, byteaddress);
+ const_cast<address_space *>(space)->set_log_unmap(log);
}
-INLINE UINT64 memory_raw_read_qword(const address_space *space, offs_t byteaddress)
+static inline bool memory_get_log_unmap(const address_space *space)
{
- if (!memory_address_outside_direct_region(space, byteaddress) || memory_set_direct_region(space, &byteaddress))
- return *(UINT64 *)&space->direct.raw[byteaddress & space->direct.bytemask];
- return memory_read_qword(space, byteaddress);
+ return space->log_unmap();
}
-
-/***************************************************************************
- FUNCTION PROTOTYPES FOR CORE READ/WRITE ROUTINES
-***************************************************************************/
-
-/* declare generic address space handlers */
-UINT8 memory_read_byte_8le(const address_space *space, offs_t address);
-UINT16 memory_read_word_8le(const address_space *space, offs_t address);
-UINT16 memory_read_word_masked_8le(const address_space *space, offs_t address, UINT16 mask);
-UINT32 memory_read_dword_8le(const address_space *space, offs_t address);
-UINT32 memory_read_dword_masked_8le(const address_space *space, offs_t address, UINT32 mask);
-UINT64 memory_read_qword_8le(const address_space *space, offs_t address);
-UINT64 memory_read_qword_masked_8le(const address_space *space, offs_t address, UINT64 mask);
-void memory_write_byte_8le(const address_space *space, offs_t address, UINT8 data);
-void memory_write_word_8le(const address_space *space, offs_t address, UINT16 data);
-void memory_write_word_masked_8le(const address_space *space, offs_t address, UINT16 data, UINT16 mask);
-void memory_write_dword_8le(const address_space *space, offs_t address, UINT32 data);
-void memory_write_dword_masked_8le(const address_space *space, offs_t address, UINT32 data, UINT32 mask);
-void memory_write_qword_8le(const address_space *space, offs_t address, UINT64 data);
-void memory_write_qword_masked_8le(const address_space *space, offs_t address, UINT64 data, UINT64 mask);
-
-UINT8 memory_read_byte_8be(const address_space *space, offs_t address);
-UINT16 memory_read_word_8be(const address_space *space, offs_t address);
-UINT16 memory_read_word_masked_8be(const address_space *space, offs_t address, UINT16 mask);
-UINT32 memory_read_dword_8be(const address_space *space, offs_t address);
-UINT32 memory_read_dword_masked_8be(const address_space *space, offs_t address, UINT32 mask);
-UINT64 memory_read_qword_8be(const address_space *space, offs_t address);
-UINT64 memory_read_qword_masked_8be(const address_space *space, offs_t address, UINT64 mask);
-void memory_write_byte_8be(const address_space *space, offs_t address, UINT8 data);
-void memory_write_word_8be(const address_space *space, offs_t address, UINT16 data);
-void memory_write_word_masked_8be(const address_space *space, offs_t address, UINT16 data, UINT16 mask);
-void memory_write_dword_8be(const address_space *space, offs_t address, UINT32 data);
-void memory_write_dword_masked_8be(const address_space *space, offs_t address, UINT32 data, UINT32 mask);
-void memory_write_qword_8be(const address_space *space, offs_t address, UINT64 data);
-void memory_write_qword_masked_8be(const address_space *space, offs_t address, UINT64 data, UINT64 mask);
-
-UINT8 memory_read_byte_16le(const address_space *space, offs_t address);
-UINT16 memory_read_word_16le(const address_space *space, offs_t address);
-UINT16 memory_read_word_masked_16le(const address_space *space, offs_t address, UINT16 mask);
-UINT32 memory_read_dword_16le(const address_space *space, offs_t address);
-UINT32 memory_read_dword_masked_16le(const address_space *space, offs_t address, UINT32 mask);
-UINT64 memory_read_qword_16le(const address_space *space, offs_t address);
-UINT64 memory_read_qword_masked_16le(const address_space *space, offs_t address, UINT64 mask);
-void memory_write_byte_16le(const address_space *space, offs_t address, UINT8 data);
-void memory_write_word_16le(const address_space *space, offs_t address, UINT16 data);
-void memory_write_word_masked_16le(const address_space *space, offs_t address, UINT16 data, UINT16 mask);
-void memory_write_dword_16le(const address_space *space, offs_t address, UINT32 data);
-void memory_write_dword_masked_16le(const address_space *space, offs_t address, UINT32 data, UINT32 mask);
-void memory_write_qword_16le(const address_space *space, offs_t address, UINT64 data);
-void memory_write_qword_masked_16le(const address_space *space, offs_t address, UINT64 data, UINT64 mask);
-
-UINT8 memory_read_byte_16be(const address_space *space, offs_t address);
-UINT16 memory_read_word_16be(const address_space *space, offs_t address);
-UINT16 memory_read_word_masked_16be(const address_space *space, offs_t address, UINT16 mask);
-UINT32 memory_read_dword_16be(const address_space *space, offs_t address);
-UINT32 memory_read_dword_masked_16be(const address_space *space, offs_t address, UINT32 mask);
-UINT64 memory_read_qword_16be(const address_space *space, offs_t address);
-UINT64 memory_read_qword_masked_16be(const address_space *space, offs_t address, UINT64 mask);
-void memory_write_byte_16be(const address_space *space, offs_t address, UINT8 data);
-void memory_write_word_16be(const address_space *space, offs_t address, UINT16 data);
-void memory_write_word_masked_16be(const address_space *space, offs_t address, UINT16 data, UINT16 mask);
-void memory_write_dword_16be(const address_space *space, offs_t address, UINT32 data);
-void memory_write_dword_masked_16be(const address_space *space, offs_t address, UINT32 data, UINT32 mask);
-void memory_write_qword_16be(const address_space *space, offs_t address, UINT64 data);
-void memory_write_qword_masked_16be(const address_space *space, offs_t address, UINT64 data, UINT64 mask);
-
-UINT8 memory_read_byte_32le(const address_space *space, offs_t address);
-UINT16 memory_read_word_32le(const address_space *space, offs_t address);
-UINT16 memory_read_word_masked_32le(const address_space *space, offs_t address, UINT16 mask);
-UINT32 memory_read_dword_32le(const address_space *space, offs_t address);
-UINT32 memory_read_dword_masked_32le(const address_space *space, offs_t address, UINT32 mask);
-UINT64 memory_read_qword_32le(const address_space *space, offs_t address);
-UINT64 memory_read_qword_masked_32le(const address_space *space, offs_t address, UINT64 mask);
-void memory_write_byte_32le(const address_space *space, offs_t address, UINT8 data);
-void memory_write_word_32le(const address_space *space, offs_t address, UINT16 data);
-void memory_write_word_masked_32le(const address_space *space, offs_t address, UINT16 data, UINT16 mask);
-void memory_write_dword_32le(const address_space *space, offs_t address, UINT32 data);
-void memory_write_dword_masked_32le(const address_space *space, offs_t address, UINT32 data, UINT32 mask);
-void memory_write_qword_32le(const address_space *space, offs_t address, UINT64 data);
-void memory_write_qword_masked_32le(const address_space *space, offs_t address, UINT64 data, UINT64 mask);
-
-UINT8 memory_read_byte_32be(const address_space *space, offs_t address);
-UINT16 memory_read_word_32be(const address_space *space, offs_t address);
-UINT16 memory_read_word_masked_32be(const address_space *space, offs_t address, UINT16 mask);
-UINT32 memory_read_dword_32be(const address_space *space, offs_t address);
-UINT32 memory_read_dword_masked_32be(const address_space *space, offs_t address, UINT32 mask);
-UINT64 memory_read_qword_32be(const address_space *space, offs_t address);
-UINT64 memory_read_qword_masked_32be(const address_space *space, offs_t address, UINT64 mask);
-void memory_write_byte_32be(const address_space *space, offs_t address, UINT8 data);
-void memory_write_word_32be(const address_space *space, offs_t address, UINT16 data);
-void memory_write_word_masked_32be(const address_space *space, offs_t address, UINT16 data, UINT16 mask);
-void memory_write_dword_32be(const address_space *space, offs_t address, UINT32 data);
-void memory_write_dword_masked_32be(const address_space *space, offs_t address, UINT32 data, UINT32 mask);
-void memory_write_qword_32be(const address_space *space, offs_t address, UINT64 data);
-void memory_write_qword_masked_32be(const address_space *space, offs_t address, UINT64 data, UINT64 mask);
-
-UINT8 memory_read_byte_64le(const address_space *space, offs_t address);
-UINT16 memory_read_word_64le(const address_space *space, offs_t address);
-UINT16 memory_read_word_masked_64le(const address_space *space, offs_t address, UINT16 mask);
-UINT32 memory_read_dword_64le(const address_space *space, offs_t address);
-UINT32 memory_read_dword_masked_64le(const address_space *space, offs_t address, UINT32 mask);
-UINT64 memory_read_qword_64le(const address_space *space, offs_t address);
-UINT64 memory_read_qword_masked_64le(const address_space *space, offs_t address, UINT64 mask);
-void memory_write_byte_64le(const address_space *space, offs_t address, UINT8 data);
-void memory_write_word_64le(const address_space *space, offs_t address, UINT16 data);
-void memory_write_word_masked_64le(const address_space *space, offs_t address, UINT16 data, UINT16 mask);
-void memory_write_dword_64le(const address_space *space, offs_t address, UINT32 data);
-void memory_write_dword_masked_64le(const address_space *space, offs_t address, UINT32 data, UINT32 mask);
-void memory_write_qword_64le(const address_space *space, offs_t address, UINT64 data);
-void memory_write_qword_masked_64le(const address_space *space, offs_t address, UINT64 data, UINT64 mask);
-
-UINT8 memory_read_byte_64be(const address_space *space, offs_t address);
-UINT16 memory_read_word_64be(const address_space *space, offs_t address);
-UINT16 memory_read_word_masked_64be(const address_space *space, offs_t address, UINT16 mask);
-UINT32 memory_read_dword_64be(const address_space *space, offs_t address);
-UINT32 memory_read_dword_masked_64be(const address_space *space, offs_t address, UINT32 mask);
-UINT64 memory_read_qword_64be(const address_space *space, offs_t address);
-UINT64 memory_read_qword_masked_64be(const address_space *space, offs_t address, UINT64 mask);
-void memory_write_byte_64be(const address_space *space, offs_t address, UINT8 data);
-void memory_write_word_64be(const address_space *space, offs_t address, UINT16 data);
-void memory_write_word_masked_64be(const address_space *space, offs_t address, UINT16 data, UINT16 mask);
-void memory_write_dword_64be(const address_space *space, offs_t address, UINT32 data);
-void memory_write_dword_masked_64be(const address_space *space, offs_t address, UINT32 data, UINT32 mask);
-void memory_write_qword_64be(const address_space *space, offs_t address, UINT64 data);
-void memory_write_qword_masked_64be(const address_space *space, offs_t address, UINT64 data, UINT64 mask);
+// declare generic address space handlers
+static inline UINT8 memory_read_byte_8le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_byte(address); }
+static inline UINT16 memory_read_word_8le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_word(address); }
+static inline UINT16 memory_read_word_masked_8le(const address_space *space, offs_t address, UINT16 mask) { return (const_cast<address_space *>(space))->read_word(address, mask); }
+static inline UINT32 memory_read_dword_8le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_dword(address); }
+static inline UINT32 memory_read_dword_masked_8le(const address_space *space, offs_t address, UINT32 mask) { return (const_cast<address_space *>(space))->read_dword(address, mask); }
+static inline UINT64 memory_read_qword_8le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_qword(address); }
+static inline UINT64 memory_read_qword_masked_8le(const address_space *space, offs_t address, UINT64 mask) { return (const_cast<address_space *>(space))->read_qword(address, mask); }
+static inline void memory_write_byte_8le(const address_space *space, offs_t address, UINT8 data) { return (const_cast<address_space *>(space))->write_byte(address, data); }
+static inline void memory_write_word_8le(const address_space *space, offs_t address, UINT16 data) { return (const_cast<address_space *>(space))->write_word(address, data); }
+static inline void memory_write_word_masked_8le(const address_space *space, offs_t address, UINT16 data, UINT16 mask) { return (const_cast<address_space *>(space))->write_word(address, data, mask); }
+static inline void memory_write_dword_8le(const address_space *space, offs_t address, UINT32 data) { return (const_cast<address_space *>(space))->write_dword(address, data); }
+static inline void memory_write_dword_masked_8le(const address_space *space, offs_t address, UINT32 data, UINT32 mask) { return (const_cast<address_space *>(space))->write_dword(address, data, mask); }
+static inline void memory_write_qword_8le(const address_space *space, offs_t address, UINT64 data) { return (const_cast<address_space *>(space))->write_qword(address, data); }
+static inline void memory_write_qword_masked_8le(const address_space *space, offs_t address, UINT64 data, UINT64 mask) { return (const_cast<address_space *>(space))->write_qword(address, data, mask); }
+
+static inline UINT8 memory_read_byte_8be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_byte(address); }
+static inline UINT16 memory_read_word_8be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_word(address); }
+static inline UINT16 memory_read_word_masked_8be(const address_space *space, offs_t address, UINT16 mask) { return (const_cast<address_space *>(space))->read_word(address, mask); }
+static inline UINT32 memory_read_dword_8be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_dword(address); }
+static inline UINT32 memory_read_dword_masked_8be(const address_space *space, offs_t address, UINT32 mask) { return (const_cast<address_space *>(space))->read_dword(address, mask); }
+static inline UINT64 memory_read_qword_8be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_qword(address); }
+static inline UINT64 memory_read_qword_masked_8be(const address_space *space, offs_t address, UINT64 mask) { return (const_cast<address_space *>(space))->read_qword(address, mask); }
+static inline void memory_write_byte_8be(const address_space *space, offs_t address, UINT8 data) { return (const_cast<address_space *>(space))->write_byte(address, data); }
+static inline void memory_write_word_8be(const address_space *space, offs_t address, UINT16 data) { return (const_cast<address_space *>(space))->write_word(address, data); }
+static inline void memory_write_word_masked_8be(const address_space *space, offs_t address, UINT16 data, UINT16 mask) { return (const_cast<address_space *>(space))->write_word(address, data, mask); }
+static inline void memory_write_dword_8be(const address_space *space, offs_t address, UINT32 data) { return (const_cast<address_space *>(space))->write_dword(address, data); }
+static inline void memory_write_dword_masked_8be(const address_space *space, offs_t address, UINT32 data, UINT32 mask) { return (const_cast<address_space *>(space))->write_dword(address, data, mask); }
+static inline void memory_write_qword_8be(const address_space *space, offs_t address, UINT64 data) { return (const_cast<address_space *>(space))->write_qword(address, data); }
+static inline void memory_write_qword_masked_8be(const address_space *space, offs_t address, UINT64 data, UINT64 mask) { return (const_cast<address_space *>(space))->write_qword(address, data, mask); }
+
+static inline UINT8 memory_read_byte_16le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_byte(address); }
+static inline UINT16 memory_read_word_16le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_word(address); }
+static inline UINT16 memory_read_word_masked_16le(const address_space *space, offs_t address, UINT16 mask) { return (const_cast<address_space *>(space))->read_word(address, mask); }
+static inline UINT32 memory_read_dword_16le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_dword(address); }
+static inline UINT32 memory_read_dword_masked_16le(const address_space *space, offs_t address, UINT32 mask) { return (const_cast<address_space *>(space))->read_dword(address, mask); }
+static inline UINT64 memory_read_qword_16le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_qword(address); }
+static inline UINT64 memory_read_qword_masked_16le(const address_space *space, offs_t address, UINT64 mask) { return (const_cast<address_space *>(space))->read_qword(address, mask); }
+static inline void memory_write_byte_16le(const address_space *space, offs_t address, UINT8 data) { return (const_cast<address_space *>(space))->write_byte(address, data); }
+static inline void memory_write_word_16le(const address_space *space, offs_t address, UINT16 data) { return (const_cast<address_space *>(space))->write_word(address, data); }
+static inline void memory_write_word_masked_16le(const address_space *space, offs_t address, UINT16 data, UINT16 mask) { return (const_cast<address_space *>(space))->write_word(address, data, mask); }
+static inline void memory_write_dword_16le(const address_space *space, offs_t address, UINT32 data) { return (const_cast<address_space *>(space))->write_dword(address, data); }
+static inline void memory_write_dword_masked_16le(const address_space *space, offs_t address, UINT32 data, UINT32 mask) { return (const_cast<address_space *>(space))->write_dword(address, data, mask); }
+static inline void memory_write_qword_16le(const address_space *space, offs_t address, UINT64 data) { return (const_cast<address_space *>(space))->write_qword(address, data); }
+static inline void memory_write_qword_masked_16le(const address_space *space, offs_t address, UINT64 data, UINT64 mask) { return (const_cast<address_space *>(space))->write_qword(address, data, mask); }
+
+static inline UINT8 memory_read_byte_16be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_byte(address); }
+static inline UINT16 memory_read_word_16be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_word(address); }
+static inline UINT16 memory_read_word_masked_16be(const address_space *space, offs_t address, UINT16 mask) { return (const_cast<address_space *>(space))->read_word(address, mask); }
+static inline UINT32 memory_read_dword_16be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_dword(address); }
+static inline UINT32 memory_read_dword_masked_16be(const address_space *space, offs_t address, UINT32 mask) { return (const_cast<address_space *>(space))->read_dword(address, mask); }
+static inline UINT64 memory_read_qword_16be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_qword(address); }
+static inline UINT64 memory_read_qword_masked_16be(const address_space *space, offs_t address, UINT64 mask) { return (const_cast<address_space *>(space))->read_qword(address, mask); }
+static inline void memory_write_byte_16be(const address_space *space, offs_t address, UINT8 data) { return (const_cast<address_space *>(space))->write_byte(address, data); }
+static inline void memory_write_word_16be(const address_space *space, offs_t address, UINT16 data) { return (const_cast<address_space *>(space))->write_word(address, data); }
+static inline void memory_write_word_masked_16be(const address_space *space, offs_t address, UINT16 data, UINT16 mask) { return (const_cast<address_space *>(space))->write_word(address, data, mask); }
+static inline void memory_write_dword_16be(const address_space *space, offs_t address, UINT32 data) { return (const_cast<address_space *>(space))->write_dword(address, data); }
+static inline void memory_write_dword_masked_16be(const address_space *space, offs_t address, UINT32 data, UINT32 mask) { return (const_cast<address_space *>(space))->write_dword(address, data, mask); }
+static inline void memory_write_qword_16be(const address_space *space, offs_t address, UINT64 data) { return (const_cast<address_space *>(space))->write_qword(address, data); }
+static inline void memory_write_qword_masked_16be(const address_space *space, offs_t address, UINT64 data, UINT64 mask) { return (const_cast<address_space *>(space))->write_qword(address, data, mask); }
+
+static inline UINT8 memory_read_byte_32le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_byte(address); }
+static inline UINT16 memory_read_word_32le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_word(address); }
+static inline UINT16 memory_read_word_masked_32le(const address_space *space, offs_t address, UINT16 mask) { return (const_cast<address_space *>(space))->read_word(address, mask); }
+static inline UINT32 memory_read_dword_32le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_dword(address); }
+static inline UINT32 memory_read_dword_masked_32le(const address_space *space, offs_t address, UINT32 mask) { return (const_cast<address_space *>(space))->read_dword(address, mask); }
+static inline UINT64 memory_read_qword_32le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_qword(address); }
+static inline UINT64 memory_read_qword_masked_32le(const address_space *space, offs_t address, UINT64 mask) { return (const_cast<address_space *>(space))->read_qword(address, mask); }
+static inline void memory_write_byte_32le(const address_space *space, offs_t address, UINT8 data) { return (const_cast<address_space *>(space))->write_byte(address, data); }
+static inline void memory_write_word_32le(const address_space *space, offs_t address, UINT16 data) { return (const_cast<address_space *>(space))->write_word(address, data); }
+static inline void memory_write_word_masked_32le(const address_space *space, offs_t address, UINT16 data, UINT16 mask) { return (const_cast<address_space *>(space))->write_word(address, data, mask); }
+static inline void memory_write_dword_32le(const address_space *space, offs_t address, UINT32 data) { return (const_cast<address_space *>(space))->write_dword(address, data); }
+static inline void memory_write_dword_masked_32le(const address_space *space, offs_t address, UINT32 data, UINT32 mask) { return (const_cast<address_space *>(space))->write_dword(address, data, mask); }
+static inline void memory_write_qword_32le(const address_space *space, offs_t address, UINT64 data) { return (const_cast<address_space *>(space))->write_qword(address, data); }
+static inline void memory_write_qword_masked_32le(const address_space *space, offs_t address, UINT64 data, UINT64 mask) { return (const_cast<address_space *>(space))->write_qword(address, data, mask); }
+
+static inline UINT8 memory_read_byte_32be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_byte(address); }
+static inline UINT16 memory_read_word_32be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_word(address); }
+static inline UINT16 memory_read_word_masked_32be(const address_space *space, offs_t address, UINT16 mask) { return (const_cast<address_space *>(space))->read_word(address, mask); }
+static inline UINT32 memory_read_dword_32be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_dword(address); }
+static inline UINT32 memory_read_dword_masked_32be(const address_space *space, offs_t address, UINT32 mask) { return (const_cast<address_space *>(space))->read_dword(address, mask); }
+static inline UINT64 memory_read_qword_32be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_qword(address); }
+static inline UINT64 memory_read_qword_masked_32be(const address_space *space, offs_t address, UINT64 mask) { return (const_cast<address_space *>(space))->read_qword(address, mask); }
+static inline void memory_write_byte_32be(const address_space *space, offs_t address, UINT8 data) { return (const_cast<address_space *>(space))->write_byte(address, data); }
+static inline void memory_write_word_32be(const address_space *space, offs_t address, UINT16 data) { return (const_cast<address_space *>(space))->write_word(address, data); }
+static inline void memory_write_word_masked_32be(const address_space *space, offs_t address, UINT16 data, UINT16 mask) { return (const_cast<address_space *>(space))->write_word(address, data, mask); }
+static inline void memory_write_dword_32be(const address_space *space, offs_t address, UINT32 data) { return (const_cast<address_space *>(space))->write_dword(address, data); }
+static inline void memory_write_dword_masked_32be(const address_space *space, offs_t address, UINT32 data, UINT32 mask) { return (const_cast<address_space *>(space))->write_dword(address, data, mask); }
+static inline void memory_write_qword_32be(const address_space *space, offs_t address, UINT64 data) { return (const_cast<address_space *>(space))->write_qword(address, data); }
+static inline void memory_write_qword_masked_32be(const address_space *space, offs_t address, UINT64 data, UINT64 mask) { return (const_cast<address_space *>(space))->write_qword(address, data, mask); }
+
+static inline UINT8 memory_read_byte_64le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_byte(address); }
+static inline UINT16 memory_read_word_64le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_word(address); }
+static inline UINT16 memory_read_word_masked_64le(const address_space *space, offs_t address, UINT16 mask) { return (const_cast<address_space *>(space))->read_word(address, mask); }
+static inline UINT32 memory_read_dword_64le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_dword(address); }
+static inline UINT32 memory_read_dword_masked_64le(const address_space *space, offs_t address, UINT32 mask) { return (const_cast<address_space *>(space))->read_dword(address, mask); }
+static inline UINT64 memory_read_qword_64le(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_qword(address); }
+static inline UINT64 memory_read_qword_masked_64le(const address_space *space, offs_t address, UINT64 mask) { return (const_cast<address_space *>(space))->read_qword(address, mask); }
+static inline void memory_write_byte_64le(const address_space *space, offs_t address, UINT8 data) { return (const_cast<address_space *>(space))->write_byte(address, data); }
+static inline void memory_write_word_64le(const address_space *space, offs_t address, UINT16 data) { return (const_cast<address_space *>(space))->write_word(address, data); }
+static inline void memory_write_word_masked_64le(const address_space *space, offs_t address, UINT16 data, UINT16 mask) { return (const_cast<address_space *>(space))->write_word(address, data, mask); }
+static inline void memory_write_dword_64le(const address_space *space, offs_t address, UINT32 data) { return (const_cast<address_space *>(space))->write_dword(address, data); }
+static inline void memory_write_dword_masked_64le(const address_space *space, offs_t address, UINT32 data, UINT32 mask) { return (const_cast<address_space *>(space))->write_dword(address, data, mask); }
+static inline void memory_write_qword_64le(const address_space *space, offs_t address, UINT64 data) { return (const_cast<address_space *>(space))->write_qword(address, data); }
+static inline void memory_write_qword_masked_64le(const address_space *space, offs_t address, UINT64 data, UINT64 mask) { return (const_cast<address_space *>(space))->write_qword(address, data, mask); }
+
+static inline UINT8 memory_read_byte_64be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_byte(address); }
+static inline UINT16 memory_read_word_64be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_word(address); }
+static inline UINT16 memory_read_word_masked_64be(const address_space *space, offs_t address, UINT16 mask) { return (const_cast<address_space *>(space))->read_word(address, mask); }
+static inline UINT32 memory_read_dword_64be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_dword(address); }
+static inline UINT32 memory_read_dword_masked_64be(const address_space *space, offs_t address, UINT32 mask) { return (const_cast<address_space *>(space))->read_dword(address, mask); }
+static inline UINT64 memory_read_qword_64be(const address_space *space, offs_t address) { return (const_cast<address_space *>(space))->read_qword(address); }
+static inline UINT64 memory_read_qword_masked_64be(const address_space *space, offs_t address, UINT64 mask) { return (const_cast<address_space *>(space))->read_qword(address, mask); }
+static inline void memory_write_byte_64be(const address_space *space, offs_t address, UINT8 data) { return (const_cast<address_space *>(space))->write_byte(address, data); }
+static inline void memory_write_word_64be(const address_space *space, offs_t address, UINT16 data) { return (const_cast<address_space *>(space))->write_word(address, data); }
+static inline void memory_write_word_masked_64be(const address_space *space, offs_t address, UINT16 data, UINT16 mask) { return (const_cast<address_space *>(space))->write_word(address, data, mask); }
+static inline void memory_write_dword_64be(const address_space *space, offs_t address, UINT32 data) { return (const_cast<address_space *>(space))->write_dword(address, data); }
+static inline void memory_write_dword_masked_64be(const address_space *space, offs_t address, UINT32 data, UINT32 mask) { return (const_cast<address_space *>(space))->write_dword(address, data, mask); }
+static inline void memory_write_qword_64be(const address_space *space, offs_t address, UINT64 data) { return (const_cast<address_space *>(space))->write_qword(address, data); }
+static inline void memory_write_qword_masked_64be(const address_space *space, offs_t address, UINT64 data, UINT64 mask) { return (const_cast<address_space *>(space))->write_qword(address, data, mask); }
#endif /* __MEMORY_H__ */
diff --git a/src/emu/sound/okim6295.c b/src/emu/sound/okim6295.c
index 4a7df1c41d2..158560eafeb 100644
--- a/src/emu/sound/okim6295.c
+++ b/src/emu/sound/okim6295.c
@@ -159,7 +159,8 @@ okim6295_device::okim6295_device(running_machine &_machine, const okim6295_devic
m_bank_installed(false),
m_bank_offs(0),
m_stream(NULL),
- m_pin7_state(m_config.m_pin7)
+ m_pin7_state(m_config.m_pin7),
+ m_direct(NULL)
{
}
@@ -170,6 +171,9 @@ okim6295_device::okim6295_device(running_machine &_machine, const okim6295_devic
void okim6295_device::device_start()
{
+ // find our direct access
+ m_direct = &space()->direct();
+
// create the stream
int divisor = m_config.m_pin7 ? 132 : 165;
m_stream = stream_create(this, 0, 1, clock() / divisor, this, static_stream_generate);
@@ -240,7 +244,7 @@ void okim6295_device::stream_generate(stream_sample_t **inputs, stream_sample_t
// iterate over voices and accumulate sample data
for (int voicenum = 0; voicenum < OKIM6295_VOICES; voicenum++)
- m_voice[voicenum].generate_adpcm(space(), outputs[0], samples);
+ m_voice[voicenum].generate_adpcm(*m_direct, outputs[0], samples);
}
@@ -289,10 +293,10 @@ void okim6295_device::set_pin7(int pin7)
READ8_DEVICE_HANDLER( okim6295_r )
{
- return downcast<okim6295_device *>(device)->status_read();
+ return downcast<okim6295_device *>(device)->read(*device->machine->m_nonspecific_space, offset);
}
-UINT8 okim6295_device::status_read()
+READ8_MEMBER( okim6295_device::read )
{
UINT8 result = 0xf0; // naname expects bits 4-7 to be 1
@@ -312,10 +316,10 @@ UINT8 okim6295_device::status_read()
WRITE8_DEVICE_HANDLER( okim6295_w )
{
- downcast<okim6295_device *>(device)->data_write(data);
+ downcast<okim6295_device *>(device)->write(*device->machine->m_nonspecific_space, offset, data);
}
-void okim6295_device::data_write(UINT8 data)
+WRITE8_MEMBER( okim6295_device::write )
{
// if a command is pending, process the second half
if (m_command != -1)
@@ -337,14 +341,14 @@ void okim6295_device::data_write(UINT8 data)
// determine the start/stop positions
offs_t base = m_command * 8;
- offs_t start = memory_raw_read_byte(space(), base + 0) << 16;
- start |= memory_raw_read_byte(space(), base + 1) << 8;
- start |= memory_raw_read_byte(space(), base + 2) << 0;
+ offs_t start = m_direct->read_raw_byte(base + 0) << 16;
+ start |= m_direct->read_raw_byte(base + 1) << 8;
+ start |= m_direct->read_raw_byte(base + 2) << 0;
start &= 0x3ffff;
- offs_t stop = memory_raw_read_byte(space(), base + 3) << 16;
- stop |= memory_raw_read_byte(space(), base + 4) << 8;
- stop |= memory_raw_read_byte(space(), base + 5) << 0;
+ offs_t stop = m_direct->read_raw_byte(base + 3) << 16;
+ stop |= m_direct->read_raw_byte(base + 4) << 8;
+ stop |= m_direct->read_raw_byte(base + 5) << 0;
stop &= 0x3ffff;
// set up the voice to play this sample
@@ -420,7 +424,7 @@ okim6295_device::okim_voice::okim_voice()
// add them to an output stream
//-------------------------------------------------
-void okim6295_device::okim_voice::generate_adpcm(const address_space *space, stream_sample_t *buffer, int samples)
+void okim6295_device::okim_voice::generate_adpcm(direct_read_data &direct, stream_sample_t *buffer, int samples)
{
// skip if not active
if (!m_playing)
@@ -430,7 +434,7 @@ void okim6295_device::okim_voice::generate_adpcm(const address_space *space, str
while (samples-- != 0)
{
// fetch the next sample byte
- int nibble = memory_raw_read_byte(space, m_base_offset + m_sample / 2) >> (((m_sample & 1) << 2) ^ 4);
+ int nibble = direct.read_raw_byte(m_base_offset + m_sample / 2) >> (((m_sample & 1) << 2) ^ 4);
// output to the buffer, scaling by the volume
// signal in range -2048..2047, volume in range 2..32 => signal * volume / 2 in range -32768..32767
diff --git a/src/emu/sound/okim6295.h b/src/emu/sound/okim6295.h
index b0311fb467d..68d72d5822f 100644
--- a/src/emu/sound/okim6295.h
+++ b/src/emu/sound/okim6295.h
@@ -122,8 +122,8 @@ public:
void set_bank_base(offs_t base);
void set_pin7(int pin7);
- UINT8 status_read();
- void data_write(UINT8 data);
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
protected:
// device-level overrides
@@ -141,7 +141,7 @@ protected:
{
public:
okim_voice();
- void generate_adpcm(const address_space *space, stream_sample_t *buffer, int samples);
+ void generate_adpcm(direct_read_data &direct, stream_sample_t *buffer, int samples);
adpcm_state m_adpcm; // current ADPCM state
bool m_playing;
@@ -156,12 +156,13 @@ protected:
const okim6295_device_config &m_config;
- okim_voice m_voice[OKIM6295_VOICES];
- INT32 m_command;
- bool m_bank_installed;
- offs_t m_bank_offs;
- sound_stream * m_stream;
- UINT8 m_pin7_state;
+ okim_voice m_voice[OKIM6295_VOICES];
+ INT32 m_command;
+ bool m_bank_installed;
+ offs_t m_bank_offs;
+ sound_stream * m_stream;
+ UINT8 m_pin7_state;
+ direct_read_data * m_direct;
static const UINT8 s_volume_table[16];
};
diff --git a/src/mame/audio/williams.c b/src/mame/audio/williams.c
index 9eabe647307..450f535a74f 100644
--- a/src/mame/audio/williams.c
+++ b/src/mame/audio/williams.c
@@ -141,7 +141,7 @@ static ADDRESS_MAP_START( williams_adpcm_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x2000, 0x2000) AM_MIRROR(0x03ff) AM_WRITE(adpcm_bank_select_w)
AM_RANGE(0x2400, 0x2401) AM_MIRROR(0x03fe) AM_DEVREADWRITE("ymsnd", ym2151_r, ym2151_w)
AM_RANGE(0x2800, 0x2800) AM_MIRROR(0x03ff) AM_DEVWRITE("dac", dac_w)
- AM_RANGE(0x2c00, 0x2c00) AM_MIRROR(0x03ff) AM_DEVREADWRITE("oki", okim6295_r, okim6295_w)
+ AM_RANGE(0x2c00, 0x2c00) AM_MIRROR(0x03ff) AM_DEVREADWRITE_MEMBER("oki", okim6295_device, read, write)
AM_RANGE(0x3000, 0x3000) AM_MIRROR(0x03ff) AM_READ(adpcm_command_r)
AM_RANGE(0x3400, 0x3400) AM_MIRROR(0x03ff) AM_DEVWRITE("oki", adpcm_6295_bank_select_w)
AM_RANGE(0x3c00, 0x3c00) AM_MIRROR(0x03ff) AM_WRITE(adpcm_talkback_w)
diff --git a/src/mame/drivers/atarig42.c b/src/mame/drivers/atarig42.c
index 8636a3dca66..034dcc2eb59 100644
--- a/src/mame/drivers/atarig42.c
+++ b/src/mame/drivers/atarig42.c
@@ -138,12 +138,12 @@ static WRITE16_HANDLER( mo_command_w )
*
*************************************/
-static DIRECT_UPDATE_HANDLER( sloop_direct_handler )
+DIRECT_UPDATE_HANDLER( atarig42_sloop_direct_handler )
{
- atarig42_state *state = space->machine->driver_data<atarig42_state>();
if (address < 0x80000)
{
- direct->raw = direct->decrypted = (UINT8 *)state->sloop_base;
+ atarig42_state *state = machine->driver_data<atarig42_state>();
+ direct.explicit_configure(0x00000, 0x7ffff, 0x7ffff, state->sloop_base);
return (offs_t)-1;
}
return address;
@@ -696,8 +696,9 @@ static DRIVER_INIT( roadriot )
state->motion_object_base = 0x200;
state->motion_object_mask = 0x1ff;
- state->sloop_base = memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x000000, 0x07ffff, 0, 0, roadriot_sloop_data_r, roadriot_sloop_data_w);
- memory_set_direct_update_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), sloop_direct_handler);
+ address_space *main = machine->device<m68000_device>("maincpu")->space(AS_PROGRAM);
+ state->sloop_base = memory_install_readwrite16_handler(main, 0x000000, 0x07ffff, 0, 0, roadriot_sloop_data_r, roadriot_sloop_data_w);
+ main->set_direct_update_handler(direct_update_delegate_create_static(atarig42_sloop_direct_handler, *machine));
asic65_config(machine, ASIC65_ROMBASED);
/*
@@ -750,8 +751,9 @@ static DRIVER_INIT( guardian )
/* put an RTS there so we don't die */
*(UINT16 *)&memory_region(machine, "maincpu")[0x80000] = 0x4E75;
- state->sloop_base = memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x000000, 0x07ffff, 0, 0, guardians_sloop_data_r, guardians_sloop_data_w);
- memory_set_direct_update_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), sloop_direct_handler);
+ address_space *main = machine->device<m68000_device>("maincpu")->space(AS_PROGRAM);
+ state->sloop_base = memory_install_readwrite16_handler(main, 0x000000, 0x07ffff, 0, 0, guardians_sloop_data_r, guardians_sloop_data_w);
+ main->set_direct_update_handler(direct_update_delegate_create_static(atarig42_sloop_direct_handler, *machine));
asic65_config(machine, ASIC65_GUARDIANS);
/*
diff --git a/src/mame/drivers/atarisy2.c b/src/mame/drivers/atarisy2.c
index d78ad64e214..b09370381e5 100644
--- a/src/mame/drivers/atarisy2.c
+++ b/src/mame/drivers/atarisy2.c
@@ -208,14 +208,13 @@ static void scanline_update(screen_device &screen, int scanline)
*
*************************************/
-static DIRECT_UPDATE_HANDLER( atarisy2_direct_handler )
+DIRECT_UPDATE_HANDLER( atarisy2_direct_handler )
{
- atarisy2_state *state = space->machine->driver_data<atarisy2_state>();
-
/* make sure slapstic area looks like ROM */
if (address >= 0x8000 && address < 0x8200)
{
- direct->raw = direct->decrypted = (UINT8 *)state->slapstic_base - 0x8000;
+ atarisy2_state *state = machine->driver_data<atarisy2_state>();
+ direct.explicit_configure(0x8000, 0x81ff, 0x1ff, (UINT8 *)state->slapstic_base);
return ~0;
}
return address;
@@ -245,7 +244,9 @@ static MACHINE_RESET( atarisy2 )
atarigen_interrupt_reset(state, update_interrupts);
atarigen_sound_io_reset(machine->device("soundcpu"));
atarigen_scanline_timer_reset(*machine->primary_screen, scanline_update, 64);
- memory_set_direct_update_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), atarisy2_direct_handler);
+
+ address_space *main = machine->device<t11_device>("maincpu")->space(AS_PROGRAM);
+ main->set_direct_update_handler(direct_update_delegate_create_static(atarisy2_direct_handler, *machine));
state->p2portwr_state = 0;
state->p2portrd_state = 0;
diff --git a/src/mame/drivers/beathead.c b/src/mame/drivers/beathead.c
index 3133c3bef00..7234c46ab95 100644
--- a/src/mame/drivers/beathead.c
+++ b/src/mame/drivers/beathead.c
@@ -98,9 +98,6 @@
#include "emu.h"
-#include "cpu/asap/asap.h"
-#include "machine/atarigen.h"
-#include "audio/atarijsa.h"
#include "includes/beathead.h"
@@ -115,8 +112,6 @@
*
*************************************/
-static void update_interrupts(running_machine *machine);
-
static TIMER_DEVICE_CALLBACK( scanline_callback )
{
beathead_state *state = timer.machine->driver_data<beathead_state>();
@@ -135,11 +130,11 @@ static TIMER_DEVICE_CALLBACK( scanline_callback )
scanline = 0;
/* set the scanline IRQ */
- state->irq_state[2] = 1;
- update_interrupts(timer.machine);
+ state->m_irq_state[2] = 1;
+ state->update_interrupts();
/* set the timer for the next one */
- timer.adjust(double_to_attotime(attotime_to_double(timer.machine->primary_screen->time_until_pos(scanline)) - state->hblank_offset), scanline);
+ timer.adjust(double_to_attotime(attotime_to_double(timer.machine->primary_screen->time_until_pos(scanline)) - state->m_hblank_offset), scanline);
}
@@ -149,6 +144,7 @@ static MACHINE_START( beathead )
}
+static void update_interrupts(running_machine *machine) { machine->driver_data<beathead_state>()->update_interrupts(); }
static MACHINE_RESET( beathead )
{
beathead_state *state = machine->driver_data<beathead_state>();
@@ -160,17 +156,17 @@ static MACHINE_RESET( beathead )
/* the code is temporarily mapped at 0 at startup */
/* just copying the first 0x40 bytes is sufficient */
- memcpy(state->ram_base, state->rom_base, 0x40);
+ memcpy(state->m_ram_base, state->m_rom_base, 0x40);
/* compute the timing of the HBLANK interrupt and set the first timer */
- state->hblank_offset = attotime_to_double(machine->primary_screen->scan_period()) * ((455. - 336. - 25.) / 455.);
+ state->m_hblank_offset = attotime_to_double(machine->primary_screen->scan_period()) * ((455. - 336. - 25.) / 455.);
timer_device *scanline_timer = machine->device<timer_device>("scan_timer");
- scanline_timer->adjust(double_to_attotime(attotime_to_double(machine->primary_screen->time_until_pos(0)) - state->hblank_offset));
+ scanline_timer->adjust(double_to_attotime(attotime_to_double(machine->primary_screen->time_until_pos(0)) - state->m_hblank_offset));
/* reset IRQs */
- state->irq_line_state = CLEAR_LINE;
- state->irq_state[0] = state->irq_state[1] = state->irq_state[2] = 0;
- state->irq_enable[0] = state->irq_enable[1] = state->irq_enable[2] = 0;
+ state->m_irq_line_state = CLEAR_LINE;
+ state->m_irq_state[0] = state->m_irq_state[1] = state->m_irq_state[2] = 0;
+ state->m_irq_enable[0] = state->m_irq_enable[1] = state->m_irq_enable[2] = 0;
}
@@ -181,54 +177,50 @@ static MACHINE_RESET( beathead )
*
*************************************/
-static void update_interrupts(running_machine *machine)
+void beathead_state::update_interrupts()
{
- beathead_state *state = machine->driver_data<beathead_state>();
int gen_int;
/* compute the combined interrupt signal */
- gen_int = state->irq_state[0] & state->irq_enable[0];
- gen_int |= state->irq_state[1] & state->irq_enable[1];
- gen_int |= state->irq_state[2] & state->irq_enable[2];
+ gen_int = m_irq_state[0] & m_irq_enable[0];
+ gen_int |= m_irq_state[1] & m_irq_enable[1];
+ gen_int |= m_irq_state[2] & m_irq_enable[2];
gen_int = gen_int ? ASSERT_LINE : CLEAR_LINE;
/* if it's changed since the last time, call through */
- if (state->irq_line_state != gen_int)
+ if (m_irq_line_state != gen_int)
{
- state->irq_line_state = gen_int;
- //if (state->irq_line_state != CLEAR_LINE)
- cputag_set_input_line(machine, "maincpu", ASAP_IRQ0, state->irq_line_state);
+ m_irq_line_state = gen_int;
+ //if (m_irq_line_state != CLEAR_LINE)
+ cputag_set_input_line(&m_machine, "maincpu", ASAP_IRQ0, m_irq_line_state);
//else
- //asap_set_irq_line(ASAP_IRQ0, state->irq_line_state);
+ //asap_set_irq_line(ASAP_IRQ0, m_irq_line_state);
}
}
-static WRITE32_HANDLER( interrupt_control_w )
+WRITE32_MEMBER( beathead_state::interrupt_control_w )
{
- beathead_state *state = space->machine->driver_data<beathead_state>();
int irq = offset & 3;
int control = (offset >> 2) & 1;
/* offsets 1-3 seem to be the enable latches for the IRQs */
if (irq != 0)
- state->irq_enable[irq - 1] = control;
+ m_irq_enable[irq - 1] = control;
/* offset 0 seems to be the interrupt ack */
else
- state->irq_state[0] = state->irq_state[1] = state->irq_state[2] = 0;
+ m_irq_state[0] = m_irq_state[1] = m_irq_state[2] = 0;
/* update the current state */
- update_interrupts(space->machine);
+ update_interrupts();
}
-static READ32_HANDLER( interrupt_control_r )
+READ32_MEMBER( beathead_state::interrupt_control_r )
{
- beathead_state *state = space->machine->driver_data<beathead_state>();
-
/* return the enables as a bitfield */
- return (state->irq_enable[0]) | (state->irq_enable[1] << 1) | (state->irq_enable[2] << 2);
+ return (m_irq_enable[0]) | (m_irq_enable[1] << 1) | (m_irq_enable[2] << 2);
}
@@ -239,24 +231,20 @@ static READ32_HANDLER( interrupt_control_r )
*
*************************************/
-static WRITE32_HANDLER( eeprom_data_w )
+WRITE32_MEMBER( beathead_state::eeprom_data_w )
{
- beathead_state *state = space->machine->driver_data<beathead_state>();
-
- if (state->eeprom_enabled)
+ if (m_eeprom_enabled)
{
mem_mask &= 0x000000ff;
- COMBINE_DATA(space->machine->generic.nvram.u32 + offset);
- state->eeprom_enabled = 0;
+ COMBINE_DATA(m_machine.generic.nvram.u32 + offset);
+ m_eeprom_enabled = 0;
}
}
-static WRITE32_HANDLER( eeprom_enable_w )
+WRITE32_MEMBER( beathead_state::eeprom_enable_w )
{
- beathead_state *state = space->machine->driver_data<beathead_state>();
-
- state->eeprom_enabled = 1;
+ m_eeprom_enabled = 1;
}
@@ -267,12 +255,11 @@ static WRITE32_HANDLER( eeprom_enable_w )
*
*************************************/
-static READ32_HANDLER( input_2_r )
+READ32_MEMBER( beathead_state::input_2_r )
{
- beathead_state *state = space->machine->driver_data<beathead_state>();
- int result = input_port_read(space->machine, "IN2");
- if (state->sound_to_cpu_ready) result ^= 0x10;
- if (state->cpu_to_sound_ready) result ^= 0x20;
+ int result = input_port_read(&m_machine, "IN2");
+ if (sound_to_cpu_ready) result ^= 0x10;
+ if (cpu_to_sound_ready) result ^= 0x20;
return result;
}
@@ -284,23 +271,23 @@ static READ32_HANDLER( input_2_r )
*
*************************************/
-static READ32_HANDLER( sound_data_r )
+READ32_MEMBER( beathead_state::sound_data_r )
{
- return atarigen_sound_r(space,offset,0xffff);
+ return atarigen_sound_r(&space, offset, 0xffff);
}
-static WRITE32_HANDLER( sound_data_w )
+WRITE32_MEMBER( beathead_state::sound_data_w )
{
if (ACCESSING_BITS_0_7)
- atarigen_sound_w(space,offset, data, mem_mask);
+ atarigen_sound_w(&space, offset, data, mem_mask);
}
-static WRITE32_HANDLER( sound_reset_w )
+WRITE32_MEMBER( beathead_state::sound_reset_w )
{
logerror("Sound reset = %d\n", !offset);
- cputag_set_input_line(space->machine, "jsa", INPUT_LINE_RESET, offset ? CLEAR_LINE : ASSERT_LINE);
+ cputag_set_input_line(&m_machine, "jsa", INPUT_LINE_RESET, offset ? CLEAR_LINE : ASSERT_LINE);
}
@@ -311,9 +298,9 @@ static WRITE32_HANDLER( sound_reset_w )
*
*************************************/
-static WRITE32_HANDLER( coin_count_w )
+WRITE32_MEMBER( beathead_state::coin_count_w )
{
- coin_counter_w(space->machine, 0, !offset);
+ coin_counter_w(&m_machine, 0, !offset);
}
@@ -325,31 +312,31 @@ static WRITE32_HANDLER( coin_count_w )
*************************************/
static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 32 )
- AM_RANGE(0x00000000, 0x0001ffff) AM_RAM AM_BASE_MEMBER(beathead_state, ram_base)
- AM_RANGE(0x01800000, 0x01bfffff) AM_ROM AM_REGION("user1", 0) AM_BASE_MEMBER(beathead_state, rom_base)
- AM_RANGE(0x40000000, 0x400007ff) AM_RAM_WRITE(eeprom_data_w) AM_BASE_SIZE_GENERIC(nvram)
- AM_RANGE(0x41000000, 0x41000003) AM_READWRITE(sound_data_r, sound_data_w)
- AM_RANGE(0x41000100, 0x41000103) AM_READ(interrupt_control_r)
- AM_RANGE(0x41000100, 0x4100011f) AM_WRITE(interrupt_control_w)
+ AM_RANGE(0x00000000, 0x0001ffff) AM_RAM AM_BASE_MEMBER(beathead_state, m_ram_base)
+ AM_RANGE(0x01800000, 0x01bfffff) AM_ROM AM_REGION("user1", 0) AM_BASE_MEMBER(beathead_state, m_rom_base)
+ AM_RANGE(0x40000000, 0x400007ff) AM_RAM_WRITE_MEMBER(beathead_state, eeprom_data_w) AM_BASE_SIZE_GENERIC(nvram)
+ AM_RANGE(0x41000000, 0x41000003) AM_READWRITE_MEMBER(beathead_state, sound_data_r, sound_data_w)
+ AM_RANGE(0x41000100, 0x41000103) AM_READ_MEMBER(beathead_state, interrupt_control_r)
+ AM_RANGE(0x41000100, 0x4100011f) AM_WRITE_MEMBER(beathead_state, interrupt_control_w)
AM_RANGE(0x41000200, 0x41000203) AM_READ_PORT("IN1")
AM_RANGE(0x41000204, 0x41000207) AM_READ_PORT("IN0")
- AM_RANGE(0x41000208, 0x4100020f) AM_WRITE(sound_reset_w)
- AM_RANGE(0x41000220, 0x41000227) AM_WRITE(coin_count_w)
- AM_RANGE(0x41000300, 0x41000303) AM_READ(input_2_r)
+ AM_RANGE(0x41000208, 0x4100020f) AM_WRITE_MEMBER(beathead_state, sound_reset_w)
+ AM_RANGE(0x41000220, 0x41000227) AM_WRITE_MEMBER(beathead_state, coin_count_w)
+ AM_RANGE(0x41000300, 0x41000303) AM_READ_MEMBER(beathead_state, input_2_r)
AM_RANGE(0x41000304, 0x41000307) AM_READ_PORT("IN3")
- AM_RANGE(0x41000400, 0x41000403) AM_WRITEONLY AM_BASE_MEMBER(beathead_state, palette_select)
- AM_RANGE(0x41000500, 0x41000503) AM_WRITE(eeprom_enable_w)
- AM_RANGE(0x41000600, 0x41000603) AM_WRITE(beathead_finescroll_w)
+ AM_RANGE(0x41000400, 0x41000403) AM_WRITEONLY AM_BASE_MEMBER(beathead_state, m_palette_select)
+ AM_RANGE(0x41000500, 0x41000503) AM_WRITE_MEMBER(beathead_state, eeprom_enable_w)
+ AM_RANGE(0x41000600, 0x41000603) AM_WRITE_MEMBER(beathead_state, finescroll_w)
AM_RANGE(0x41000700, 0x41000703) AM_WRITE(watchdog_reset32_w)
- AM_RANGE(0x42000000, 0x4201ffff) AM_RAM_WRITE(beathead_palette_w) AM_BASE_GENERIC(paletteram)
- AM_RANGE(0x43000000, 0x43000007) AM_READWRITE(beathead_hsync_ram_r, beathead_hsync_ram_w)
+ AM_RANGE(0x42000000, 0x4201ffff) AM_RAM_WRITE_MEMBER(beathead_state, palette_w) AM_BASE_MEMBER(beathead_state, m_paletteram)
+ AM_RANGE(0x43000000, 0x43000007) AM_READWRITE_MEMBER(beathead_state, hsync_ram_r, hsync_ram_w)
AM_RANGE(0x8df80000, 0x8df80003) AM_READNOP /* noisy x4 during scanline int */
- AM_RANGE(0x8f380000, 0x8f3fffff) AM_WRITE(beathead_vram_latch_w)
- AM_RANGE(0x8f900000, 0x8f97ffff) AM_WRITE(beathead_vram_transparent_w)
- AM_RANGE(0x8f980000, 0x8f9fffff) AM_RAM AM_BASE_GENERIC(videoram)
- AM_RANGE(0x8fb80000, 0x8fbfffff) AM_WRITE(beathead_vram_bulk_w)
- AM_RANGE(0x8fff8000, 0x8fff8003) AM_WRITEONLY AM_BASE_MEMBER(beathead_state, vram_bulk_latch)
- AM_RANGE(0x9e280000, 0x9e2fffff) AM_WRITE(beathead_vram_copy_w)
+ AM_RANGE(0x8f380000, 0x8f3fffff) AM_WRITE_MEMBER(beathead_state, vram_latch_w)
+ AM_RANGE(0x8f900000, 0x8f97ffff) AM_WRITE_MEMBER(beathead_state, vram_transparent_w)
+ AM_RANGE(0x8f980000, 0x8f9fffff) AM_RAM AM_BASE_MEMBER(beathead_state, m_videoram)
+ AM_RANGE(0x8fb80000, 0x8fbfffff) AM_WRITE_MEMBER(beathead_state, vram_bulk_w)
+ AM_RANGE(0x8fff8000, 0x8fff8003) AM_WRITEONLY AM_BASE_MEMBER(beathead_state, m_vram_bulk_latch)
+ AM_RANGE(0x9e280000, 0x9e2fffff) AM_WRITE_MEMBER(beathead_state, vram_copy_w)
ADDRESS_MAP_END
@@ -480,26 +467,24 @@ ROM_END
*/
-static UINT32 *speedup_data;
-static READ32_HANDLER( speedup_r )
+READ32_MEMBER( beathead_state::speedup_r )
{
- int result = *speedup_data;
- if ((cpu_get_previouspc(space->cpu) & 0xfffff) == 0x006f0 && result == cpu_get_reg(space->cpu, ASAP_R3))
- cpu_spinuntil_int(space->cpu);
+ int result = *m_speedup_data;
+ if ((cpu_get_previouspc(space.cpu) & 0xfffff) == 0x006f0 && result == cpu_get_reg(space.cpu, ASAP_R3))
+ cpu_spinuntil_int(space.cpu);
return result;
}
-static UINT32 *movie_speedup_data;
-static READ32_HANDLER( movie_speedup_r )
+READ32_MEMBER( beathead_state::movie_speedup_r )
{
- int result = *movie_speedup_data;
- if ((cpu_get_previouspc(space->cpu) & 0xfffff) == 0x00a88 && (cpu_get_reg(space->cpu, ASAP_R28) & 0xfffff) == 0x397c0 &&
- movie_speedup_data[4] == cpu_get_reg(space->cpu, ASAP_R1))
+ int result = *m_movie_speedup_data;
+ if ((cpu_get_previouspc(space.cpu) & 0xfffff) == 0x00a88 && (cpu_get_reg(space.cpu, ASAP_R28) & 0xfffff) == 0x397c0 &&
+ m_movie_speedup_data[4] == cpu_get_reg(space.cpu, ASAP_R1))
{
- UINT32 temp = (INT16)result + movie_speedup_data[4] * 262;
- if (temp - (UINT32)cpu_get_reg(space->cpu, ASAP_R15) < (UINT32)cpu_get_reg(space->cpu, ASAP_R23))
- cpu_spinuntil_int(space->cpu);
+ UINT32 temp = (INT16)result + m_movie_speedup_data[4] * 262;
+ if (temp - (UINT32)cpu_get_reg(space.cpu, ASAP_R15) < (UINT32)cpu_get_reg(space.cpu, ASAP_R23))
+ cpu_spinuntil_int(space.cpu);
}
return result;
}
@@ -514,12 +499,14 @@ static READ32_HANDLER( movie_speedup_r )
static DRIVER_INIT( beathead )
{
+ beathead_state *state = machine->driver_data<beathead_state>();
+
/* initialize the common systems */
atarijsa_init(machine, "IN2", 0x0040);
/* prepare the speedups */
- speedup_data = memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x00000ae8, 0x00000aeb, 0, 0, speedup_r);
- movie_speedup_data = memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x00000804, 0x00000807, 0, 0, movie_speedup_r);
+ state->m_speedup_data = state->m_maincpu.space(AS_PROGRAM)->install_handler(0x00000ae8, 0x00000aeb, 0, 0, read32_delegate_create(beathead_state, speedup_r, *state));
+ state->m_movie_speedup_data = state->m_maincpu.space(AS_PROGRAM)->install_handler(0x00000804, 0x00000807, 0, 0, read32_delegate_create(beathead_state, movie_speedup_r, *state));
}
diff --git a/src/mame/drivers/cps3.c b/src/mame/drivers/cps3.c
index 7760540026f..35293fca310 100644
--- a/src/mame/drivers/cps3.c
+++ b/src/mame/drivers/cps3.c
@@ -607,7 +607,7 @@ INLINE void cps3_drawgfxzoom(bitmap_t *dest_bmp,const rectangle *clip,const gfx_
-static DIRECT_UPDATE_HANDLER( cps3_direct_handler );
+DIRECT_UPDATE_HANDLER( cps3_direct_handler );
/* Encryption */
@@ -706,7 +706,9 @@ static DRIVER_INIT( cps3 )
cps3_0xc0000000_ram_decrypted = auto_alloc_array(machine, UINT32, 0x400/4);
- memory_set_direct_update_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), cps3_direct_handler);
+
+ address_space *main = machine->device<sh2_device>("maincpu")->space(AS_PROGRAM);
+ main->set_direct_update_handler(direct_update_delegate_create_static(cps3_direct_handler, *machine));
// flash roms
@@ -1263,38 +1265,37 @@ static WRITE32_HANDLER( cps3_0xc0000000_ram_w )
-static DIRECT_UPDATE_HANDLER( cps3_direct_handler )
+DIRECT_UPDATE_HANDLER( cps3_direct_handler )
{
// if(DEBUG_PRINTF) printf("address %04x\n",address);
/* BIOS ROM */
if (address < 0x80000)
{
- direct->raw = direct->decrypted = memory_region(space->machine, "user1");
+ direct.explicit_configure(0x00000, 0x7ffff, 0x7ffff, *direct.space().m_machine.region("user1"));
return ~0;
}
/* RAM */
else if (address >= 0x06000000 && address <= 0x06ffffff)
{
- direct->decrypted = (UINT8*)decrypted_gamerom-0x06000000;
- direct->raw = (UINT8*)decrypted_gamerom-0x06000000;
+ UINT8 *decrypted = (UINT8*)decrypted_gamerom;
+ UINT8 *raw = decrypted;
- if (cps3_altEncryption) direct->raw = (UINT8*) cps3_user4region-0x06000000;
+ if (cps3_altEncryption) raw = (UINT8*) cps3_user4region;
+ direct.explicit_configure(0x06000000, 0x06ffffff, 0x00ffffff, raw, decrypted);
return ~0;
}
else if (address >= 0xc0000000 && address <= 0xc00003ff)
{
//direct->decrypted = (void*)cps3_0xc0000000_ram_decrypted;
- direct->decrypted = (UINT8*)cps3_0xc0000000_ram_decrypted-0xc0000000;
- direct->raw = (UINT8*)cps3_0xc0000000_ram-0xc0000000;
+ direct.explicit_configure(0xc0000000, 0xc00003ff, 0x3ff, (UINT8*)cps3_0xc0000000_ram, (UINT8*)cps3_0xc0000000_ram_decrypted);
return ~0;
}
/* anything else falls through to NOPs */
- direct->decrypted = (UINT8*)cps3_nops-address;
- direct->raw = (UINT8*)cps3_nops-address;
+ direct.explicit_configure(address, address, 0, (UINT8*)cps3_nops, (UINT8*)cps3_nops);
return ~0;
}
diff --git a/src/mame/drivers/hng64.c b/src/mame/drivers/hng64.c
index 0f785074bd6..d54201a2bc0 100644
--- a/src/mame/drivers/hng64.c
+++ b/src/mame/drivers/hng64.c
@@ -1106,9 +1106,9 @@ ADDRESS_MAP_END
#define KL5C_MMU_A(xxx) ( (xxx==0) ? 0x0000 : (hng64_com_mmu_mem[((xxx-1)*2)+1] << 2) | ((hng64_com_mmu_mem[(xxx-1)*2] & 0xc0) >> 6) )
#define KL5C_MMU_B(xxx) ( (xxx==0) ? 0x0000 : (hng64_com_mmu_mem[(xxx-1)*2] & 0x3f) )
-static DIRECT_UPDATE_HANDLER( KL5C80_direct_handler )
+DIRECT_UPDATE_HANDLER( KL5C80_direct_handler )
{
- direct->raw = direct->decrypted = hng64_com_op_base;
+ direct.explicit_configure(0x0000, 0xffff, 0xffff, hng64_com_op_base);
return ~0;
}
@@ -1677,7 +1677,9 @@ static MACHINE_RESET(hyperneo)
hng64_com_virtual_mem[i] = rom[i];
KL5C80_virtual_mem_sync();
- memory_set_direct_update_handler(cputag_get_address_space(machine, "comm", ADDRESS_SPACE_PROGRAM), KL5C80_direct_handler);
+
+ address_space *space = machine->device<z80_device>("comm")->space(AS_PROGRAM);
+ space->set_direct_update_handler(direct_update_delegate_create_static(KL5C80_direct_handler, *machine));
cputag_set_input_line(machine, "comm", INPUT_LINE_RESET, PULSE_LINE); // reset the CPU and let 'er rip
// cputag_set_input_line(machine, "comm", INPUT_LINE_HALT, ASSERT_LINE); // hold on there pardner...
diff --git a/src/mame/drivers/missile.c b/src/mame/drivers/missile.c
index 4af5bd69007..6416acb5f08 100644
--- a/src/mame/drivers/missile.c
+++ b/src/mame/drivers/missile.c
@@ -445,7 +445,7 @@ static TIMER_CALLBACK( adjust_cpu_speed )
}
-static DIRECT_UPDATE_HANDLER( missile_direct_handler )
+DIRECT_UPDATE_HANDLER( missile_direct_handler )
{
/* offset accounts for lack of A15 decoding */
int offset = address & 0x8000;
@@ -454,14 +454,14 @@ static DIRECT_UPDATE_HANDLER( missile_direct_handler )
/* RAM? */
if (address < 0x4000)
{
- direct->raw = direct->decrypted = space->machine->generic.videoram.u8 - offset;
+ direct.explicit_configure(0x0000 | offset, 0x3fff | offset, 0x3fff, direct.space().m_machine.generic.videoram.u8);
return ~0;
}
/* ROM? */
else if (address >= 0x5000)
{
- direct->raw = direct->decrypted = memory_region(space->machine, "maincpu") - offset;
+ direct.explicit_configure(0x5000 | offset, 0x7fff | offset, 0x7fff, direct.space().m_machine.region("maincpu")->base() + 0x5000);
return ~0;
}
@@ -477,7 +477,8 @@ static MACHINE_START( missile )
flipscreen = 0;
/* set up an opcode base handler since we use mapped handlers for RAM */
- memory_set_direct_update_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), missile_direct_handler);
+ address_space *space = machine->device<m6502_device>("maincpu")->space(AS_PROGRAM);
+ space->set_direct_update_handler(direct_update_delegate_create_static(missile_direct_handler, *machine));
/* create a timer to speed/slow the CPU */
cpu_timer = timer_alloc(machine, adjust_cpu_speed, NULL);
diff --git a/src/mame/drivers/plygonet.c b/src/mame/drivers/plygonet.c
index 1f318839424..eac08c6d5e5 100644
--- a/src/mame/drivers/plygonet.c
+++ b/src/mame/drivers/plygonet.c
@@ -319,26 +319,26 @@ static READ16_HANDLER( dsp56k_bootload_r )
return 0x7fff;
}
-static DIRECT_UPDATE_HANDLER( plygonet_dsp56k_direct_handler )
+DIRECT_UPDATE_HANDLER( plygonet_dsp56k_direct_handler )
{
- polygonet_state *state = space->machine->driver_data<polygonet_state>();
+ polygonet_state *state = machine->driver_data<polygonet_state>();
/* Call the dsp's update handler first */
- if (state->dsp56k_update_handler != NULL)
+ if (!state->dsp56k_update_handler.isnull())
{
- if ((*state->dsp56k_update_handler)(space, address, direct) == ~0)
+ if (state->dsp56k_update_handler(direct, address) == ~0)
return ~0;
}
/* If the requested region wasn't in there, see if it needs to be caught driver-side */
if (address >= (0x7000<<1) && address <= (0x7fff<<1))
{
- direct->raw = direct->decrypted = (UINT8*)(state->dsp56k_p_mirror) - (0x7000<<1);
+ direct.explicit_configure(0x7000<<1, 0x7fff<<1, 0xfff<<1, state->dsp56k_p_mirror);
return ~0;
}
else if (address >= (0x8000<<1) && address <= (0x87ff<<1))
{
- direct->raw = direct->decrypted = (UINT8*)(state->dsp56k_p_8000) - (0x8000<<1);
+ direct.explicit_configure(0x8000<<1, 0x87ff<<1, 0x7ff<<1, state->dsp56k_p_8000);
return ~0;
}
@@ -764,7 +764,8 @@ static DRIVER_INIT(polygonet)
state->dsp56k_bank04_ram = auto_alloc_array_clear(machine, UINT16, 2 * 8 * dsp56k_bank04_size);
/* The dsp56k occasionally executes out of mapped memory */
- state->dsp56k_update_handler = memory_set_direct_update_handler(cputag_get_address_space(machine, "dsp", ADDRESS_SPACE_PROGRAM), plygonet_dsp56k_direct_handler);
+ address_space *space = machine->device<dsp56k_device>("dsp")->space(AS_PROGRAM);
+ state->dsp56k_update_handler = space->set_direct_update_handler(direct_update_delegate_create_static(plygonet_dsp56k_direct_handler, *machine));
/* save states */
state_save_register_global_pointer(machine, state->dsp56k_bank00_ram, 2 * 8 * dsp56k_bank00_size);
diff --git a/src/mame/drivers/starwars.c b/src/mame/drivers/starwars.c
index 9a38c10473e..c79b05d42d6 100644
--- a/src/mame/drivers/starwars.c
+++ b/src/mame/drivers/starwars.c
@@ -127,12 +127,12 @@ static WRITE8_HANDLER( esb_slapstic_w )
*
*************************************/
-static DIRECT_UPDATE_HANDLER( esb_setdirect )
+DIRECT_UPDATE_HANDLER( esb_setdirect )
{
/* if we are in the slapstic region, process it */
if ((address & 0xe000) == 0x8000)
{
- offs_t pc = cpu_get_pc(space->cpu);
+ offs_t pc = cpu_get_pc(&direct.space().device());
/* filter out duplicates; we get these because the handler gets called for
multiple reasons:
@@ -143,7 +143,7 @@ static DIRECT_UPDATE_HANDLER( esb_setdirect )
{
slapstic_last_pc = pc;
slapstic_last_address = address;
- esb_slapstic_tweak(space, address & 0x1fff);
+ esb_slapstic_tweak(&direct.space(), address & 0x1fff);
}
return ~0;
}
@@ -527,7 +527,8 @@ static DRIVER_INIT( esb )
slapstic_base = &rom[0x08000];
/* install an opcode base handler */
- memory_set_direct_update_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), esb_setdirect);
+ address_space *space = machine->device<m6809_device>("maincpu")->space(AS_PROGRAM);
+ space->set_direct_update_handler(direct_update_delegate_create_static(esb_setdirect, *machine));
/* install read/write handlers for it */
memory_install_readwrite8_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x8000, 0x9fff, 0, 0, esb_slapstic_r, esb_slapstic_w);
diff --git a/src/mame/drivers/vcombat.c b/src/mame/drivers/vcombat.c
index d2aaf9d80b9..2fc4d2d33fb 100644
--- a/src/mame/drivers/vcombat.c
+++ b/src/mame/drivers/vcombat.c
@@ -389,21 +389,21 @@ static MACHINE_RESET( shadfgtr )
}
-static DIRECT_UPDATE_HANDLER( vid_0_direct_handler )
+DIRECT_UPDATE_HANDLER( vcombat_vid_0_direct_handler )
{
if (address >= 0xfffc0000 && address <= 0xffffffff)
{
- direct->raw = direct->decrypted = ((UINT8*)vid_0_shared_RAM) - 0xfffc0000;
+ direct.explicit_configure(0xfffc0000, 0xffffffff, 0x3ffff, vid_0_shared_RAM);
return ~0;
}
return address;
}
-static DIRECT_UPDATE_HANDLER( vid_1_direct_handler )
+DIRECT_UPDATE_HANDLER( vcombat_vid_1_direct_handler )
{
if (address >= 0xfffc0000 && address <= 0xffffffff)
{
- direct->raw = direct->decrypted = ((UINT8*)vid_1_shared_RAM) - 0xfffc0000;
+ direct.explicit_configure(0xfffc0000, 0xffffffff, 0x3ffff, vid_1_shared_RAM);
return ~0;
}
return address;
@@ -415,8 +415,11 @@ static DRIVER_INIT( vcombat )
UINT8 *ROM = memory_region(machine, "maincpu");
/* The two i860s execute out of RAM */
- memory_set_direct_update_handler(cputag_get_address_space(machine, "vid_0", ADDRESS_SPACE_PROGRAM), vid_0_direct_handler);
- memory_set_direct_update_handler(cputag_get_address_space(machine, "vid_1", ADDRESS_SPACE_PROGRAM), vid_1_direct_handler);
+ address_space *space = machine->device<i860_device>("vid_0")->space(AS_PROGRAM);
+ space->set_direct_update_handler(direct_update_delegate_create_static(vcombat_vid_0_direct_handler, *machine));
+
+ space = machine->device<i860_device>("vid_1")->space(AS_PROGRAM);
+ space->set_direct_update_handler(direct_update_delegate_create_static(vcombat_vid_1_direct_handler, *machine));
/* Allocate the 68000 framebuffers */
m68k_framebuffer[0] = auto_alloc_array(machine, UINT16, 0x8000);
@@ -459,7 +462,8 @@ static DRIVER_INIT( shadfgtr )
i860_framebuffer[1][1] = NULL;
/* The i860 executes out of RAM */
- memory_set_direct_update_handler(cputag_get_address_space(machine, "vid_0", ADDRESS_SPACE_PROGRAM), vid_0_direct_handler);
+ address_space *space = machine->device<i860_device>("vid_0")->space(AS_PROGRAM);
+ space->set_direct_update_handler(direct_update_delegate_create_static(vcombat_vid_0_direct_handler, *machine));
}
diff --git a/src/mame/drivers/vegas.c b/src/mame/drivers/vegas.c
index 027a49835e5..092aa138dc5 100644
--- a/src/mame/drivers/vegas.c
+++ b/src/mame/drivers/vegas.c
@@ -1675,6 +1675,8 @@ static void remap_dynamic_addresses(running_machine *machine)
/* now remap everything */
if (LOG_DYNAMIC) logerror("remap_dynamic_addresses:\n");
+ address_space *space = const_cast<address_space *>(machine->device<cpu_device>("maincpu")->space(AS_PROGRAM));
+ assert(space != NULL);
for (addr = 0; addr < dynamic_count; addr++)
{
if (LOG_DYNAMIC) logerror(" installing: %08X-%08X %s,%s\n", dynamic[addr].start, dynamic[addr].end, dynamic[addr].rdname, dynamic[addr].wrname);
@@ -1682,12 +1684,15 @@ static void remap_dynamic_addresses(running_machine *machine)
if (dynamic[addr].mread == NOP_HANDLER)
memory_nop_read(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), dynamic[addr].start, dynamic[addr].end, 0, 0);
else if (dynamic[addr].mread != NULL)
- _memory_install_handler32(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), dynamic[addr].start, dynamic[addr].end, 0, 0, dynamic[addr].mread, dynamic[addr].rdname, NULL, NULL, 0);
+ space->install_legacy_handler(dynamic[addr].start, dynamic[addr].end, 0, 0, dynamic[addr].mread, dynamic[addr].rdname);
if (dynamic[addr].mwrite != NULL)
- _memory_install_handler32(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), dynamic[addr].start, dynamic[addr].end, 0, 0, NULL, NULL, dynamic[addr].mwrite, dynamic[addr].wrname, 0);
+ space->install_legacy_handler(dynamic[addr].start, dynamic[addr].end, 0, 0, dynamic[addr].mwrite, dynamic[addr].wrname);
if (dynamic[addr].dread != NULL || dynamic[addr].dwrite != NULL)
- _memory_install_device_handler32(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), dynamic[addr].device, dynamic[addr].start, dynamic[addr].end, 0, 0, dynamic[addr].dread, dynamic[addr].rdname, dynamic[addr].dwrite, dynamic[addr].wrname, 0);
+ {
+ space->install_legacy_handler(*dynamic[addr].device, dynamic[addr].start, dynamic[addr].end, 0, 0, dynamic[addr].dread, dynamic[addr].rdname);
+ space->install_legacy_handler(*dynamic[addr].device, dynamic[addr].start, dynamic[addr].end, 0, 0, dynamic[addr].dwrite, dynamic[addr].wrname);
+ }
}
if (LOG_DYNAMIC)
diff --git a/src/mame/includes/beathead.h b/src/mame/includes/beathead.h
index 0ce41ed1aba..eda9188168c 100644
--- a/src/mame/includes/beathead.h
+++ b/src/mame/includes/beathead.h
@@ -5,6 +5,8 @@
*************************************************************************/
#include "machine/atarigen.h"
+#include "cpu/asap/asap.h"
+#include "audio/atarijsa.h"
class beathead_state : public atarigen_state
{
@@ -12,28 +14,61 @@ public:
static driver_data_t *alloc(running_machine &machine) { return auto_alloc_clear(&machine, beathead_state(machine)); }
beathead_state(running_machine &machine)
- : atarigen_state(machine) { }
-
- UINT32 * vram_bulk_latch;
- UINT32 * palette_select;
-
- UINT32 finescroll;
- offs_t vram_latch_offset;
-
- offs_t hsyncram_offset;
- offs_t hsyncram_start;
- UINT8 hsyncram[0x800];
-
- UINT32 * ram_base;
- UINT32 * rom_base;
-
- double hblank_offset;
-
- UINT8 irq_line_state;
- UINT8 irq_enable[3];
- UINT8 irq_state[3];
-
- UINT8 eeprom_enabled;
+ : atarigen_state(machine),
+ m_maincpu(*machine.device<asap_device>("maincpu")) { }
+
+ asap_device & m_maincpu;
+
+ UINT32 * m_videoram;
+ UINT32 * m_paletteram;
+
+ UINT32 * m_vram_bulk_latch;
+ UINT32 * m_palette_select;
+
+ UINT32 m_finescroll;
+ offs_t m_vram_latch_offset;
+
+ offs_t m_hsyncram_offset;
+ offs_t m_hsyncram_start;
+ UINT8 m_hsyncram[0x800];
+
+ UINT32 * m_ram_base;
+ UINT32 * m_rom_base;
+
+ double m_hblank_offset;
+
+ UINT8 m_irq_line_state;
+ UINT8 m_irq_enable[3];
+ UINT8 m_irq_state[3];
+
+ UINT8 m_eeprom_enabled;
+
+ UINT32 * m_speedup_data;
+ UINT32 * m_movie_speedup_data;
+
+ // in drivers/beathead.c
+ void update_interrupts();
+ DECLARE_WRITE32_MEMBER( interrupt_control_w );
+ DECLARE_READ32_MEMBER( interrupt_control_r );
+ DECLARE_WRITE32_MEMBER( eeprom_data_w );
+ DECLARE_WRITE32_MEMBER( eeprom_enable_w );
+ DECLARE_READ32_MEMBER( input_2_r );
+ DECLARE_READ32_MEMBER( sound_data_r );
+ DECLARE_WRITE32_MEMBER( sound_data_w );
+ DECLARE_WRITE32_MEMBER( sound_reset_w );
+ DECLARE_WRITE32_MEMBER( coin_count_w );
+ DECLARE_READ32_MEMBER( speedup_r );
+ DECLARE_READ32_MEMBER( movie_speedup_r );
+
+ // in video/beathead.c
+ DECLARE_WRITE32_MEMBER( vram_transparent_w );
+ DECLARE_WRITE32_MEMBER( vram_bulk_w );
+ DECLARE_WRITE32_MEMBER( vram_latch_w );
+ DECLARE_WRITE32_MEMBER( vram_copy_w );
+ DECLARE_WRITE32_MEMBER( finescroll_w );
+ DECLARE_WRITE32_MEMBER( palette_w );
+ DECLARE_READ32_MEMBER( hsync_ram_r );
+ DECLARE_WRITE32_MEMBER( hsync_ram_w );
};
@@ -41,12 +76,3 @@ public:
VIDEO_START( beathead );
VIDEO_UPDATE( beathead );
-
-WRITE32_HANDLER( beathead_vram_transparent_w );
-WRITE32_HANDLER( beathead_vram_bulk_w );
-WRITE32_HANDLER( beathead_vram_latch_w );
-WRITE32_HANDLER( beathead_vram_copy_w );
-WRITE32_HANDLER( beathead_finescroll_w );
-WRITE32_HANDLER( beathead_palette_w );
-READ32_HANDLER( beathead_hsync_ram_r );
-WRITE32_HANDLER( beathead_hsync_ram_w );
diff --git a/src/mame/includes/plygonet.h b/src/mame/includes/plygonet.h
index f63a9eea481..1463093f7ad 100644
--- a/src/mame/includes/plygonet.h
+++ b/src/mame/includes/plygonet.h
@@ -18,7 +18,7 @@ public:
UINT16* dsp56k_bank04_ram;
int cur_sound_region;
- direct_update_func dsp56k_update_handler;
+ direct_update_delegate dsp56k_update_handler;
/* TTL text plane stuff */
int ttl_gfx_index;
diff --git a/src/mame/machine/archimds.c b/src/mame/machine/archimds.c
index 798837ffae4..f8da3ff3a77 100644
--- a/src/mame/machine/archimds.c
+++ b/src/mame/machine/archimds.c
@@ -279,7 +279,7 @@ WRITE32_HANDLER(archimedes_memc_logical_w)
}
}
-static DIRECT_UPDATE_HANDLER( a310_setopbase )
+DIRECT_UPDATE_HANDLER( a310_setopbase )
{
// if we're not in logical memory, MAME can do the right thing
if (address > 0x1ffffff)
@@ -290,19 +290,14 @@ static DIRECT_UPDATE_HANDLER( a310_setopbase )
// if the boot ROM is mapped in, do some trickery to make it show up
if (memc_latchrom)
{
- direct->bytemask = 0x1fffff;
- direct->bytestart = 0;
- direct->byteend = 0x1fffff;
- direct->raw = direct->decrypted = memory_region(space->machine, "maincpu");
+ direct.explicit_configure(0x000000, 0x1fffff, 0x1fffff, *direct.space().m_machine.region("maincpu"));
}
else // executing from logical memory
{
- UINT32 page = address / page_sizes[memc_pagesize];
-
- direct->bytemask = page_sizes[memc_pagesize]-1;
- direct->bytestart = page * page_sizes[memc_pagesize];
- direct->byteend = direct->bytestart + direct->bytemask;
- direct->raw = direct->decrypted = (UINT8 *)&archimedes_memc_physmem[(memc_pages[page] * page_sizes[memc_pagesize])>>2];
+ offs_t pagesize = page_sizes[memc_pagesize];
+ UINT32 page = address / pagesize;
+
+ direct.explicit_configure(page * pagesize, page * pagesize - 1, pagesize - 1, &archimedes_memc_physmem[(memc_pages[page] * pagesize)>>2]);
}
return ~0;
@@ -310,7 +305,8 @@ static DIRECT_UPDATE_HANDLER( a310_setopbase )
void archimedes_driver_init(running_machine *machine)
{
- memory_set_direct_update_handler( cputag_get_address_space( machine, "maincpu", ADDRESS_SPACE_PROGRAM ), a310_setopbase);
+ address_space *space = machine->device<arm_device>("maincpu")->space(AS_PROGRAM);
+ space->set_direct_update_handler(direct_update_delegate_create_static(a310_setopbase, *machine));
}
static const char *const ioc_regnames[] =
diff --git a/src/mame/machine/atarigen.c b/src/mame/machine/atarigen.c
index 39a9f1afdd2..7454cf49d21 100644
--- a/src/mame/machine/atarigen.c
+++ b/src/mame/machine/atarigen.c
@@ -491,9 +491,9 @@ static STATE_POSTLOAD( slapstic_postload )
}
-static DIRECT_UPDATE_HANDLER( atarigen_slapstic_setdirect )
+DIRECT_UPDATE_HANDLER( atarigen_slapstic_setdirect )
{
- atarigen_state *state = space->machine->driver_data<atarigen_state>();
+ atarigen_state *state = machine->driver_data<atarigen_state>();
/* if we jump to an address in the slapstic region, tweak the slapstic
at that address and return ~0; this will cause us to be called on
@@ -501,12 +501,12 @@ static DIRECT_UPDATE_HANDLER( atarigen_slapstic_setdirect )
address &= ~state->slapstic_mirror;
if (address >= state->slapstic_base && address < state->slapstic_base + 0x8000)
{
- offs_t pc = cpu_get_previouspc(space->cpu);
+ offs_t pc = cpu_get_previouspc(&direct.space().device());
if (pc != state->slapstic_last_pc || address != state->slapstic_last_address)
{
state->slapstic_last_pc = pc;
state->slapstic_last_address = address;
- atarigen_slapstic_r(space, (address >> 1) & 0x3fff, 0xffff);
+ atarigen_slapstic_r(&direct.space(), (address >> 1) & 0x3fff, 0xffff);
}
return ~0;
}
@@ -548,7 +548,9 @@ void atarigen_slapstic_init(running_device *device, offs_t base, offs_t mirror,
/* install an opcode base handler if we are a 68000 or variant */
state->slapstic_base = base;
state->slapstic_mirror = mirror;
- memory_set_direct_update_handler(cpu_get_address_space(device, ADDRESS_SPACE_PROGRAM), atarigen_slapstic_setdirect);
+
+ address_space *space = downcast<cpu_device *>(device)->space(AS_PROGRAM);
+ space->set_direct_update_handler(direct_update_delegate_create_static(atarigen_slapstic_setdirect, *device->machine));
}
}
diff --git a/src/mame/machine/fddebug.c b/src/mame/machine/fddebug.c
index d75c480ed80..fa24c07afe2 100644
--- a/src/mame/machine/fddebug.c
+++ b/src/mame/machine/fddebug.c
@@ -460,7 +460,7 @@ INLINE int addr_is_valid(const address_space *space, UINT32 addr, UINT32 flags)
return 0;
/* if we're invalid, fail */
- if (strcmp(memory_get_handler_string(space, 0, addr), "segaic16_memory_mapper_lsb_r") == 0)
+ if (strcmp(const_cast<address_space *>(space)->get_handler_string(ROW_READ, addr), "segaic16_memory_mapper_lsb_r") == 0)
return 2;
return 1;
diff --git a/src/mame/machine/n64.c b/src/mame/machine/n64.c
index 27fac6bd97a..9ecd5fe14f1 100644
--- a/src/mame/machine/n64.c
+++ b/src/mame/machine/n64.c
@@ -1965,7 +1965,7 @@ static UINT32 cic_status = 0x00000000;
READ32_HANDLER( n64_pif_ram_r )
{
/*mame_printf_debug( "pif_ram_r: %08X, %08X = %08X\n", offset << 2, mem_mask, ( ( pif_ram[offset*4+0] << 24 ) | ( pif_ram[offset*4+1] << 16 ) | ( pif_ram[offset*4+2] << 8 ) | ( pif_ram[offset*4+3] << 0 ) ) & mem_mask );*/
- if(!space->debugger_access)
+ if(!space->debugger_access())
{
if( offset == ( 0x24 / 4 ) )
{
diff --git a/src/mame/machine/snes.c b/src/mame/machine/snes.c
index 4c68ae885d7..419913fc370 100644
--- a/src/mame/machine/snes.c
+++ b/src/mame/machine/snes.c
@@ -957,7 +957,7 @@ READ8_HANDLER( snes_r_bank1 )
else
value = snes_ram[offset];
- if(!space->debugger_access)
+ if(!space->debugger_access())
cpu_adjust_icount(space->cpu, -snes_bank_0x00_0x3f_cycles(space->machine, offset));
return value;
@@ -1020,7 +1020,7 @@ READ8_HANDLER( snes_r_bank2 )
else
value = snes_ram[0x300000 + offset];
- if(!space->debugger_access)
+ if(!space->debugger_access())
cpu_adjust_icount(space->cpu, -snes_bank_0x00_0x3f_cycles(space->machine, offset));
return value;
@@ -1061,7 +1061,7 @@ READ8_HANDLER( snes_r_bank3 )
else /* Mode 21 & 25 + SuperFX games */
value = snes_ram[0x400000 + offset];
- if(!space->debugger_access)
+ if(!space->debugger_access())
cpu_adjust_icount(space->cpu, -8);
return value;
@@ -1099,7 +1099,7 @@ READ8_HANDLER( snes_r_bank4 )
else if (state->cart[0].mode & 0x0a) /* Mode 21 & 25 */
value = snes_ram[0x600000 + offset];
- if(!space->debugger_access)
+ if(!space->debugger_access())
cpu_adjust_icount(space->cpu, -8);
return value;
@@ -1135,7 +1135,7 @@ READ8_HANDLER( snes_r_bank5 )
else
value = snes_ram[0x700000 + offset];
- if(!space->debugger_access)
+ if(!space->debugger_access())
cpu_adjust_icount(space->cpu, -8);
return value;
@@ -1183,7 +1183,7 @@ READ8_HANDLER( snes_r_bank6 )
else
value = snes_ram[0x800000 + offset];
- if(!space->debugger_access)
+ if(!space->debugger_access())
cpu_adjust_icount(space->cpu, -snes_bank_0x80_0xbf_cycles(space->machine, offset));
return value;
@@ -1236,7 +1236,7 @@ READ8_HANDLER( snes_r_bank7 )
else /* Mode 21 & 25 + SuperFX Games */
value = snes_ram[0xc00000 + offset];
- if(!space->debugger_access)
+ if(!space->debugger_access())
cpu_adjust_icount(space->cpu, -((snes_ram[MEMSEL] & 1) ? 6 : 8));
return value;
@@ -1290,7 +1290,7 @@ WRITE8_HANDLER( snes_w_bank1 )
else
logerror( "(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset );
- if(!space->debugger_access)
+ if(!space->debugger_access())
cpu_adjust_icount(space->cpu, -snes_bank_0x00_0x3f_cycles(space->machine, offset));
}
@@ -1347,7 +1347,7 @@ WRITE8_HANDLER( snes_w_bank2 )
else
logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset + 0x300000);
- if(!space->debugger_access)
+ if(!space->debugger_access())
cpu_adjust_icount(space->cpu, -snes_bank_0x00_0x3f_cycles(space->machine, offset));
}
@@ -1373,7 +1373,7 @@ WRITE8_HANDLER( snes_w_bank4 )
else if (state->cart[0].mode & 0x0a)
logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset + 0x600000);
- if(!space->debugger_access)
+ if(!space->debugger_access())
cpu_adjust_icount(space->cpu, -8);
}
@@ -1398,7 +1398,7 @@ WRITE8_HANDLER( snes_w_bank5 )
else if (state->cart[0].mode & 0x0a)
logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset + 0x700000);
- if(!space->debugger_access)
+ if(!space->debugger_access())
cpu_adjust_icount(space->cpu, -8);
}
@@ -1446,7 +1446,7 @@ WRITE8_HANDLER( snes_w_bank6 )
else
logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset + 0x800000);
- if(!space->debugger_access)
+ if(!space->debugger_access())
cpu_adjust_icount(space->cpu, -snes_bank_0x80_0xbf_cycles(space->machine, offset));
}
@@ -1486,7 +1486,7 @@ WRITE8_HANDLER( snes_w_bank7 )
else if (state->cart[0].mode & 0x0a)
logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset + 0xc00000);
- if(!space->debugger_access)
+ if(!space->debugger_access())
cpu_adjust_icount(space->cpu, -((snes_ram[MEMSEL] & 1) ? 6 : 8));
}
@@ -1677,15 +1677,15 @@ static void snes_init_ram( running_machine *machine )
}
-static DIRECT_UPDATE_HANDLER( spc_direct )
+DIRECT_UPDATE_HANDLER( snes_spc_direct )
{
- direct->raw = direct->decrypted = spc_get_ram(space->machine->device("spc700"));
+ direct.explicit_configure(0x0000, 0xffff, 0xffff, spc_get_ram(machine->device("spc700")));
return ~0;
}
-static DIRECT_UPDATE_HANDLER( snes_direct )
+DIRECT_UPDATE_HANDLER( snes_direct )
{
- direct->raw = direct->decrypted = snes_ram;
+ direct.explicit_configure(0x0000, 0xffff, 0xffff, snes_ram);
return ~0;
}
@@ -1694,14 +1694,14 @@ MACHINE_START( snes )
snes_state *state = machine->driver_data<snes_state>();
int i;
- memory_set_direct_update_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), snes_direct);
- memory_set_direct_update_handler(cputag_get_address_space(machine, "soundcpu", ADDRESS_SPACE_PROGRAM), spc_direct);
-
state->maincpu = machine->device<_5a22_device>("maincpu");
state->soundcpu = machine->device<spc700_device>("soundcpu");
state->spc700 = machine->device<snes_sound_sound_device>("spc700");
state->superfx = machine->device<cpu_device>("superfx");
+ state->maincpu->space(AS_PROGRAM)->set_direct_update_handler(direct_update_delegate_create_static(snes_direct, *machine));
+ state->soundcpu->space(AS_PROGRAM)->set_direct_update_handler(direct_update_delegate_create_static(snes_spc_direct, *machine));
+
// power-on sets these registers like this
snes_ram[WRIO] = 0xff;
snes_ram[WRMPYA] = 0xff;
diff --git a/src/mame/video/beathead.c b/src/mame/video/beathead.c
index 9d9f11eac29..92005a7617b 100644
--- a/src/mame/video/beathead.c
+++ b/src/mame/video/beathead.c
@@ -18,11 +18,11 @@
VIDEO_START( beathead )
{
beathead_state *state = machine->driver_data<beathead_state>();
- state_save_register_global(machine, state->finescroll);
- state_save_register_global(machine, state->vram_latch_offset);
- state_save_register_global(machine, state->hsyncram_offset);
- state_save_register_global(machine, state->hsyncram_start);
- state_save_register_global_array(machine, state->hsyncram);
+ state_save_register_global(machine, state->m_finescroll);
+ state_save_register_global(machine, state->m_vram_latch_offset);
+ state_save_register_global(machine, state->m_hsyncram_offset);
+ state_save_register_global(machine, state->m_hsyncram_start);
+ state_save_register_global_array(machine, state->m_hsyncram);
}
@@ -33,21 +33,19 @@ VIDEO_START( beathead )
*
*************************************/
-WRITE32_HANDLER( beathead_vram_transparent_w )
+WRITE32_MEMBER( beathead_state::vram_transparent_w )
{
/* writes to this area appear to handle transparency */
if (!(data & 0x000000ff)) mem_mask &= ~0x000000ff;
if (!(data & 0x0000ff00)) mem_mask &= ~0x0000ff00;
if (!(data & 0x00ff0000)) mem_mask &= ~0x00ff0000;
if (!(data & 0xff000000)) mem_mask &= ~0xff000000;
- COMBINE_DATA(&space->machine->generic.videoram.u32[offset]);
+ COMBINE_DATA(&m_videoram[offset]);
}
-WRITE32_HANDLER( beathead_vram_bulk_w )
+WRITE32_MEMBER( beathead_state::vram_bulk_w )
{
- beathead_state *state = space->machine->driver_data<beathead_state>();
-
/* it appears that writes to this area pass in a mask for 4 words in VRAM */
/* allowing them to be filled from a preset latch */
offset &= ~3;
@@ -55,29 +53,24 @@ WRITE32_HANDLER( beathead_vram_bulk_w )
/* for now, just handle the bulk fill case; the others we'll catch later */
if (data == 0x0f0f0f0f)
- space->machine->generic.videoram.u32[offset+0] =
- space->machine->generic.videoram.u32[offset+1] =
- space->machine->generic.videoram.u32[offset+2] =
- space->machine->generic.videoram.u32[offset+3] = *state->vram_bulk_latch;
+ m_videoram[offset+0] = m_videoram[offset+1] = m_videoram[offset+2] = m_videoram[offset+3] = *m_vram_bulk_latch;
else
logerror("Detected bulk VRAM write with mask %08x\n", data);
}
-WRITE32_HANDLER( beathead_vram_latch_w )
+WRITE32_MEMBER( beathead_state::vram_latch_w )
{
/* latch the address */
- beathead_state *state = space->machine->driver_data<beathead_state>();
- state->vram_latch_offset = (4 * offset) & 0x7ffff;
+ m_vram_latch_offset = (4 * offset) & 0x7ffff;
}
-WRITE32_HANDLER( beathead_vram_copy_w )
+WRITE32_MEMBER( beathead_state::vram_copy_w )
{
/* copy from VRAM to VRAM, for 1024 bytes */
- beathead_state *state = space->machine->driver_data<beathead_state>();
offs_t dest_offset = (4 * offset) & 0x7ffff;
- memcpy(&space->machine->generic.videoram.u32[dest_offset / 4], &space->machine->generic.videoram.u32[state->vram_latch_offset / 4], 0x400);
+ memcpy(&m_videoram[dest_offset / 4], &m_videoram[m_vram_latch_offset / 4], 0x400);
}
@@ -88,17 +81,16 @@ WRITE32_HANDLER( beathead_vram_copy_w )
*
*************************************/
-WRITE32_HANDLER( beathead_finescroll_w )
+WRITE32_MEMBER( beathead_state::finescroll_w )
{
- beathead_state *state = space->machine->driver_data<beathead_state>();
- UINT32 oldword = state->finescroll;
- UINT32 newword = COMBINE_DATA(&state->finescroll);
+ UINT32 oldword = m_finescroll;
+ UINT32 newword = COMBINE_DATA(&m_finescroll);
/* if VBLANK is going off on a scanline other than the last, suspend time */
- if ((oldword & 8) && !(newword & 8) && space->machine->primary_screen->vpos() != 261)
+ if ((oldword & 8) && !(newword & 8) && space.machine->primary_screen->vpos() != 261)
{
- logerror("Suspending time! (scanline = %d)\n", space->machine->primary_screen->vpos());
- cputag_set_input_line(space->machine, "maincpu", INPUT_LINE_HALT, ASSERT_LINE);
+ logerror("Suspending time! (scanline = %d)\n", space.machine->primary_screen->vpos());
+ cputag_set_input_line(space.machine, "maincpu", INPUT_LINE_HALT, ASSERT_LINE);
}
}
@@ -110,13 +102,13 @@ WRITE32_HANDLER( beathead_finescroll_w )
*
*************************************/
-WRITE32_HANDLER( beathead_palette_w )
+WRITE32_MEMBER( beathead_state::palette_w )
{
- int newword = COMBINE_DATA(&space->machine->generic.paletteram.u32[offset]);
+ int newword = COMBINE_DATA(&m_paletteram[offset]);
int r = ((newword >> 9) & 0x3e) | ((newword >> 15) & 0x01);
int g = ((newword >> 4) & 0x3e) | ((newword >> 15) & 0x01);
int b = ((newword << 1) & 0x3e) | ((newword >> 15) & 0x01);
- palette_set_color_rgb(space->machine, offset, pal6bit(r), pal6bit(g), pal6bit(b));
+ palette_set_color_rgb(space.machine, offset, pal6bit(r), pal6bit(g), pal6bit(b));
}
@@ -127,36 +119,32 @@ WRITE32_HANDLER( beathead_palette_w )
*
*************************************/
-READ32_HANDLER( beathead_hsync_ram_r )
+READ32_MEMBER( beathead_state::hsync_ram_r )
{
- beathead_state *state = space->machine->driver_data<beathead_state>();
-
/* offset 0 is probably write-only */
if (offset == 0)
- logerror("%08X:Unexpected HSYNC RAM read at offset 0\n", cpu_get_previouspc(space->cpu));
+ logerror("%08X:Unexpected HSYNC RAM read at offset 0\n", cpu_get_previouspc(space.cpu));
/* offset 1 reads the data */
else
- return state->hsyncram[state->hsyncram_offset];
+ return m_hsyncram[m_hsyncram_offset];
return 0;
}
-WRITE32_HANDLER( beathead_hsync_ram_w )
+WRITE32_MEMBER( beathead_state::hsync_ram_w )
{
- beathead_state *state = space->machine->driver_data<beathead_state>();
-
/* offset 0 selects the address, and can specify the start address */
if (offset == 0)
{
- COMBINE_DATA(&state->hsyncram_offset);
- if (state->hsyncram_offset & 0x800)
- state->hsyncram_start = state->hsyncram_offset & 0x7ff;
+ COMBINE_DATA(&m_hsyncram_offset);
+ if (m_hsyncram_offset & 0x800)
+ m_hsyncram_start = m_hsyncram_offset & 0x7ff;
}
/* offset 1 writes the data */
else
- COMBINE_DATA(&state->hsyncram[state->hsyncram_offset]);
+ COMBINE_DATA(&m_hsyncram[m_hsyncram_offset]);
}
@@ -170,24 +158,24 @@ WRITE32_HANDLER( beathead_hsync_ram_w )
VIDEO_UPDATE( beathead )
{
beathead_state *state = screen->machine->driver_data<beathead_state>();
- UINT8 *videoram = screen->machine->generic.videoram.u8;
+ UINT8 *videoram = reinterpret_cast<UINT8 *>(state->m_videoram);
int x, y;
/* generate the final screen */
for (y = cliprect->min_y; y <= cliprect->max_y; y++)
{
- pen_t pen_base = (*state->palette_select & 0x7f) * 256;
+ pen_t pen_base = (*state->m_palette_select & 0x7f) * 256;
UINT16 scanline[336];
/* blanking */
- if (state->finescroll & 8)
+ if (state->m_finescroll & 8)
for (x = cliprect->min_x; x <= cliprect->max_x; x++)
scanline[x] = pen_base;
/* non-blanking */
else
{
- offs_t scanline_offset = state->vram_latch_offset + (state->finescroll & 3);
+ offs_t scanline_offset = state->m_vram_latch_offset + (state->m_finescroll & 3);
offs_t src = scanline_offset + cliprect->min_x;
/* unswizzle the scanline first */