mirror of
https://github.com/holub/mame
synced 2025-04-27 18:53:05 +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)
|
||||
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);
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
@ -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
|
||||
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
|
||||
-------------------------------------------------*/
|
||||
|
Loading…
Reference in New Issue
Block a user