summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Curt Coder <curtcoder@mail.com>2011-04-16 16:53:16 +0000
committer Curt Coder <curtcoder@mail.com>2011-04-16 16:53:16 +0000
commitf575cd348f3a898d86684e9a2e40bf8c3e2877a6 (patch)
tree0e302ac756ec0dc65b6841a46406747d51343029
parent2541451a8a9caa76ea6ed183114a84377c1c73de (diff)
Implemented 16-bit device callbacks. [Curt Coder]
-rw-r--r--src/emu/devcb.c159
-rw-r--r--src/emu/devcb.h104
2 files changed, 263 insertions, 0 deletions
diff --git a/src/emu/devcb.c b/src/emu/devcb.c
index 5907abc7a3f..d603156dfff 100644
--- a/src/emu/devcb.c
+++ b/src/emu/devcb.c
@@ -361,3 +361,162 @@ void devcb_resolve_write8(devcb_resolved_write8 *resolved, const devcb_write8 *c
}
}
}
+
+
+/*-------------------------------------------------
+ devcb_resolve_read16 - convert a static
+ 16-bit read definition to a live definition
+-------------------------------------------------*/
+
+static READ16_DEVICE_HANDLER( trampoline_read_port_to_read16 )
+{
+ return input_port_read_direct((const input_port_config *)device);
+}
+
+static READ16_DEVICE_HANDLER( trampoline_read_line_to_read16 )
+{
+ const devcb_resolved_read16 *resolved = (const devcb_resolved_read16 *)device;
+ return (*resolved->real.readline)((device_t *)resolved->realtarget);
+}
+
+void devcb_resolve_read16(devcb_resolved_read16 *resolved, const devcb_read16 *config, device_t *device)
+{
+ /* reset the resolved structure */
+ memset(resolved, 0, sizeof(*resolved));
+
+ /* input port handlers */
+ if (config->type == DEVCB_TYPE_INPUT)
+ {
+ resolved->target = device->machine().port(config->tag);
+ if (resolved->target == NULL)
+ fatalerror("devcb_resolve_read16: unable to find input port '%s' (requested by %s '%s')", config->tag, device->name(), device->tag());
+ resolved->read = trampoline_read_port_to_read16;
+ }
+
+ /* address space handlers */
+ else if (config->type >= DEVCB_TYPE_MEMORY(AS_PROGRAM) && config->type < DEVCB_TYPE_MEMORY(ADDRESS_SPACES) && config->readspace != NULL)
+ {
+ FPTR spacenum = (FPTR)config->type - (FPTR)DEVCB_TYPE_MEMORY(AS_PROGRAM);
+
+ device_t *targetdev = device->siblingdevice(config->tag);
+ if (targetdev == NULL)
+ fatalerror("devcb_resolve_read16: unable to find device '%s' (requested by %s '%s')", config->tag, device->name(), device->tag());
+ device_memory_interface *memory;
+ if (!targetdev->interface(memory))
+ fatalerror("devcb_resolve_read16: device '%s' (requested by %s '%s') has no memory", config->tag, device->name(), device->tag());
+
+ resolved->target = targetdev->memory().space(spacenum);
+ if (resolved->target == NULL)
+ fatalerror("devcb_resolve_read16: unable to find device '%s' space %d (requested by %s '%s')", config->tag, (int)spacenum, device->name(), device->tag());
+ resolved->read = (read16_device_func)config->readspace;
+ }
+
+ /* device handlers */
+ else if ((config->type == DEVCB_TYPE_DEVICE || config->type == DEVCB_TYPE_SELF || config->type == DEVCB_TYPE_DRIVER) && (config->readline != NULL || config->readdevice != NULL))
+ {
+ if (config->type == DEVCB_TYPE_SELF)
+ resolved->target = device;
+ else if (config->type == DEVCB_TYPE_DRIVER)
+ resolved->target = device->machine().driver_data();
+ else
+ if (strcmp(config->tag, DEVICE_SELF_OWNER) == 0)
+ resolved->target = device->owner();
+ else
+ resolved->target = device->siblingdevice(config->tag);
+
+ if (resolved->target == NULL)
+ fatalerror("devcb_resolve_read16: unable to find device '%s' (requested by %s '%s')", config->tag, device->name(), device->tag());
+
+ /* read16 to read16 is direct */
+ if (config->readdevice != NULL)
+ resolved->read = config->readdevice;
+
+ /* read16 to read_line goes through a trampoline */
+ else
+ {
+ resolved->realtarget = resolved->target;
+ resolved->real.readline = config->readline;
+ resolved->target = resolved;
+ resolved->read = trampoline_read_line_to_read16;
+ }
+ }
+}
+
+
+/*-------------------------------------------------
+ devcb_resolve_write16 - convert a static
+ 16-bit write definition to a live definition
+-------------------------------------------------*/
+
+static WRITE16_DEVICE_HANDLER( trampoline_write_port_to_write16 )
+{
+ input_port_write_direct((const input_port_config *)device, data, 0xff);
+}
+
+static WRITE16_DEVICE_HANDLER( trampoline_write_line_to_write16 )
+{
+ const devcb_resolved_write16 *resolved = (const devcb_resolved_write16 *)device;
+ (*resolved->real.writeline)((device_t *)resolved->realtarget, (data & 1) ? ASSERT_LINE : CLEAR_LINE);
+}
+
+void devcb_resolve_write16(devcb_resolved_write16 *resolved, const devcb_write16 *config, device_t *device)
+{
+ /* reset the resolved structure */
+ memset(resolved, 0, sizeof(*resolved));
+
+ if (config->type == DEVCB_TYPE_INPUT)
+ {
+ resolved->target = device->machine().port(config->tag);
+ if (resolved->target == NULL)
+ fatalerror("devcb_resolve_read_line: unable to find input port '%s' (requested by %s '%s')", config->tag, device->name(), device->tag());
+ resolved->write = trampoline_write_port_to_write16;
+ }
+
+ /* address space handlers */
+ else if (config->type >= DEVCB_TYPE_MEMORY(AS_PROGRAM) && config->type < DEVCB_TYPE_MEMORY(ADDRESS_SPACES) && config->writespace != NULL)
+ {
+ FPTR spacenum = (FPTR)config->type - (FPTR)DEVCB_TYPE_MEMORY(AS_PROGRAM);
+
+ device_t *targetdev = device->siblingdevice(config->tag);
+ if (targetdev == NULL)
+ fatalerror("devcb_resolve_write16: unable to find device '%s' (requested by %s '%s')", config->tag, device->name(), device->tag());
+ device_memory_interface *memory;
+ if (!targetdev->interface(memory))
+ fatalerror("devcb_resolve_write16: device '%s' (requested by %s '%s') has no memory", config->tag, device->name(), device->tag());
+
+ resolved->target = targetdev->memory().space(spacenum);
+ if (resolved->target == NULL)
+ fatalerror("devcb_resolve_write16: unable to find device '%s' space %d (requested by %s '%s')", config->tag, (int)spacenum, device->name(), device->tag());
+ resolved->write = (write16_device_func)config->writespace;
+ }
+
+ /* device handlers */
+ else if ((config->type == DEVCB_TYPE_DEVICE || config->type == DEVCB_TYPE_SELF || config->type == DEVCB_TYPE_DRIVER) && (config->writeline != NULL || config->writedevice != NULL))
+ {
+ if (config->type == DEVCB_TYPE_SELF)
+ resolved->target = device;
+ else if (config->type == DEVCB_TYPE_DRIVER)
+ resolved->target = device->machine().driver_data();
+ else
+ if (strcmp(config->tag, DEVICE_SELF_OWNER) == 0)
+ resolved->target = device->owner();
+ else
+ resolved->target = device->siblingdevice(config->tag);
+
+ if (resolved->target == NULL)
+ fatalerror("devcb_resolve_write16: unable to find device '%s' (requested by %s '%s')", config->tag, device->name(), device->tag());
+
+ /* write16 to write16 is direct */
+ if (config->writedevice != NULL)
+ resolved->write = config->writedevice;
+
+ /* write16 to write_line goes through a trampoline */
+ else
+ {
+ resolved->realtarget = resolved->target;
+ resolved->real.writeline = config->writeline;
+ resolved->target = resolved;
+ resolved->write = trampoline_write_line_to_write16;
+ }
+ }
+}
diff --git a/src/emu/devcb.h b/src/emu/devcb.h
index 6641c2fdaf1..2fb37a3c1fa 100644
--- a/src/emu/devcb.h
+++ b/src/emu/devcb.h
@@ -20,6 +20,8 @@
write_line_device_func: (device, data)
read8_device_func: (device, offset)
write8_device_func: (device, offset, data)
+ read16_device_func: (device, offset)
+ write16_device_func: (device, offset, data)
The adapted callback types supported are:
@@ -31,6 +33,10 @@
write8_device_func: (device, offset, data)
read8_space_func: (space, offset)
write8_space_func: (space, offset, data)
+ read16_device_func: (device, offset)
+ write16_device_func: (device, offset, data)
+ read16_space_func: (space, offset)
+ write16_space_func: (space, offset, data)
***************************************************************************/
@@ -78,6 +84,14 @@ UINT8 devcb_stub(device_t *device, offs_t offset)
return (target->*_Function)(*memory_nonspecific_space(device->machine()), offset, 0xff);
}
+// static template for a read16 stub function that calls through a given READ16_MEMBER
+template<class _Class, UINT16 (_Class::*_Function)(address_space &, offs_t, UINT16)>
+UINT16 devcb_stub(device_t *device, offs_t offset)
+{
+ _Class *target = downcast<_Class *>(device);
+ return (target->*_Function)(*memory_nonspecific_space(device->machine()), offset, 0xffff);
+}
+
// static template for a write_line stub function that calls through a given WRITE_LINE_MEMBER
template<class _Class, void (_Class::*_Function)(int state)>
void devcb_line_stub(device_t *device, int state)
@@ -94,6 +108,14 @@ void devcb_stub(device_t *device, offs_t offset, UINT8 data)
(target->*_Function)(*memory_nonspecific_space(device->machine()), offset, data, 0xff);
}
+// static template for a write16 stub function that calls through a given WRITE16_MEMBER
+template<class _Class, void (_Class::*_Function)(address_space &, offs_t, UINT16, UINT16)>
+void devcb_stub(device_t *device, offs_t offset, UINT16 data)
+{
+ _Class *target = downcast<_Class *>(device);
+ (target->*_Function)(*memory_nonspecific_space(device->machine()), offset, data, 0xffff);
+}
+
#define DEVCB_NULL { DEVCB_TYPE_NULL }
/* standard line or read/write handlers with the calling device passed */
@@ -261,6 +283,57 @@ struct _devcb_resolved_write8
};
+/* static structure used for device configuration when the desired callback type is a read16_device_func */
+typedef struct _devcb_read16 devcb_read16;
+struct _devcb_read16
+{
+ UINT32 type; /* one of the special DEVCB_TYPE values */
+ const char * tag; /* tag of target, where appropriate */
+ read_line_device_func readline; /* read line function */
+ read16_device_func readdevice; /* read device function */
+ read16_space_func readspace; /* read space function */
+};
+
+typedef struct _devcb_resolved_read16 devcb_resolved_read16;
+struct _devcb_resolved_read16
+{
+ const void * target; /* target object */
+ read16_device_func read; /* read function */
+ const void * realtarget; /* real target object for stubs */
+ union
+ {
+ read16_device_func readdevice;
+ read16_space_func readspace;
+ read_line_device_func readline;
+ } real; /* real read function for stubs */
+};
+
+
+/* static structure used for device configuration when the desired callback type is a write16_device_func */
+typedef struct _devcb_write16 devcb_write16;
+struct _devcb_write16
+{
+ UINT32 type; /* one of the special DEVCB_TYPE values */
+ const char * tag; /* tag of target, where appropriate */
+ write_line_device_func writeline; /* write line function */
+ write16_device_func writedevice; /* write device function */
+ write16_space_func writespace; /* write space function */
+};
+
+typedef struct _devcb_resolved_write16 devcb_resolved_write16;
+struct _devcb_resolved_write16
+{
+ const void * target; /* target object */
+ write16_device_func write; /* write function */
+ const void * realtarget; /* real target object for stubs */
+ union
+ {
+ write16_device_func writedevice;
+ write16_space_func writespace;
+ write_line_device_func writeline;
+ } real; /* real write function for stubs */
+};
+
/***************************************************************************
FUNCTION PROTOTYPES
@@ -281,6 +354,12 @@ void devcb_resolve_read8(devcb_resolved_read8 *resolved, const devcb_read8 *conf
/* convert a static 8-bit write definition to a live definition */
void devcb_resolve_write8(devcb_resolved_write8 *resolved, const devcb_write8 *config, device_t *device);
+/* convert a static 16-bit read definition to a live definition */
+void devcb_resolve_read16(devcb_resolved_read16 *resolved, const devcb_read16 *config, device_t *device);
+
+/* convert a static 16-bit write definition to a live definition */
+void devcb_resolve_write16(devcb_resolved_write16 *resolved, const devcb_write16 *config, device_t *device);
+
/***************************************************************************
@@ -310,6 +389,17 @@ INLINE int devcb_call_read8(const devcb_resolved_read8 *resolved, offs_t offset)
/*-------------------------------------------------
+ devcb_call_read16 - call through a
+ resolved read16 handler
+-------------------------------------------------*/
+
+INLINE int devcb_call_read16(const devcb_resolved_read16 *resolved, offs_t offset)
+{
+ return (resolved->read != NULL) ? (*resolved->read)((device_t *)resolved->target, offset, 0xffff) : 0;
+}
+
+
+/*-------------------------------------------------
devcb_call_write_line - call through a
resolved write_line handler
-------------------------------------------------*/
@@ -332,6 +422,19 @@ INLINE void devcb_call_write8(const devcb_resolved_write8 *resolved, offs_t offs
(*resolved->write)((device_t *)resolved->target, offset, data);
}
+
+/*-------------------------------------------------
+ devcb_call_write16 - call through a
+ resolved write16 handler
+-------------------------------------------------*/
+
+INLINE void devcb_call_write16(const devcb_resolved_write16 *resolved, offs_t offset, UINT16 data)
+{
+ if (resolved->write != NULL)
+ (*resolved->write)((device_t *)resolved->target, offset, data, 0xffff);
+}
+
+
/*-------------------------------------------------
devcb_line_gnd_r - input tied to GND
-------------------------------------------------*/
@@ -341,6 +444,7 @@ INLINE READ_LINE_DEVICE_HANDLER( devcb_line_gnd_r )
return 0;
}
+
/*-------------------------------------------------
devcb_line_vcc_r - input tied to Vcc
-------------------------------------------------*/