mirror of
https://github.com/holub/mame
synced 2025-05-01 04:06:58 +03:00
Implemented 16-bit device callbacks. [Curt Coder]
This commit is contained in:
parent
2541451a8a
commit
f575cd348f
159
src/emu/devcb.c
159
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
104
src/emu/devcb.h
104
src/emu/devcb.h
@ -20,6 +20,8 @@
|
|||||||
write_line_device_func: (device, data)
|
write_line_device_func: (device, data)
|
||||||
read8_device_func: (device, offset)
|
read8_device_func: (device, offset)
|
||||||
write8_device_func: (device, offset, data)
|
write8_device_func: (device, offset, data)
|
||||||
|
read16_device_func: (device, offset)
|
||||||
|
write16_device_func: (device, offset, data)
|
||||||
|
|
||||||
The adapted callback types supported are:
|
The adapted callback types supported are:
|
||||||
|
|
||||||
@ -31,6 +33,10 @@
|
|||||||
write8_device_func: (device, offset, data)
|
write8_device_func: (device, offset, data)
|
||||||
read8_space_func: (space, offset)
|
read8_space_func: (space, offset)
|
||||||
write8_space_func: (space, offset, data)
|
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);
|
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
|
// static template for a write_line stub function that calls through a given WRITE_LINE_MEMBER
|
||||||
template<class _Class, void (_Class::*_Function)(int state)>
|
template<class _Class, void (_Class::*_Function)(int state)>
|
||||||
void devcb_line_stub(device_t *device, 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);
|
(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 }
|
#define DEVCB_NULL { DEVCB_TYPE_NULL }
|
||||||
|
|
||||||
/* standard line or read/write handlers with the calling device passed */
|
/* 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
|
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 */
|
/* 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);
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@ -309,6 +388,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
|
devcb_call_write_line - call through a
|
||||||
resolved write_line handler
|
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);
|
(*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
|
devcb_line_gnd_r - input tied to GND
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
@ -341,6 +444,7 @@ INLINE READ_LINE_DEVICE_HANDLER( devcb_line_gnd_r )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
devcb_line_vcc_r - input tied to Vcc
|
devcb_line_vcc_r - input tied to Vcc
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
Loading…
Reference in New Issue
Block a user