mirror of
https://github.com/holub/mame
synced 2025-05-30 01:23:07 +03:00
458 lines
17 KiB
C++
458 lines
17 KiB
C++
/***************************************************************************
|
|
|
|
devcb.h
|
|
|
|
Device callback interface helpers.
|
|
|
|
Copyright Nicola Salmoria and the MAME Team.
|
|
Visit http://mamedev.org for licensing and usage restrictions.
|
|
|
|
****************************************************************************
|
|
|
|
These functions are used to adapt multiple read/write handler types
|
|
to be used with device I/O. In general, a device is expected to
|
|
declare its desired callback type, and these functions allow other
|
|
callback types to be adapted appropriately.
|
|
|
|
The desired callback types currently supported include:
|
|
|
|
read_line_device_func: (device)
|
|
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:
|
|
|
|
input port (port)
|
|
cpu input line (cpu input line)
|
|
read_line_device_func: (device)
|
|
write_line_device_func: (device, data)
|
|
read8_device_func: (device, offset)
|
|
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)
|
|
|
|
***************************************************************************/
|
|
|
|
#pragma once
|
|
|
|
#ifndef __EMU_H__
|
|
#error Dont include this file directly; include emu.h instead.
|
|
#endif
|
|
|
|
#ifndef __DEVCB_H__
|
|
#define __DEVCB_H__
|
|
|
|
|
|
/***************************************************************************
|
|
CONSTANTS
|
|
***************************************************************************/
|
|
|
|
#define DEVCB_TYPE_NULL (0)
|
|
#define DEVCB_TYPE_SELF (1)
|
|
#define DEVCB_TYPE_INPUT (2)
|
|
#define DEVCB_TYPE_DEVICE (3)
|
|
#define DEVCB_TYPE_DRIVER (4)
|
|
#define DEVCB_TYPE_MEMORY(space) (5 + (space))
|
|
#define DEVCB_TYPE_CPU_LINE(line) (5 + ADDRESS_SPACES + (line))
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
MACROS
|
|
***************************************************************************/
|
|
|
|
// static template for a read_line stub function that calls through a given READ_LINE_MEMBER
|
|
template<class _Class, int (_Class::*_Function)()>
|
|
int devcb_line_stub(device_t *device)
|
|
{
|
|
_Class *target = downcast<_Class *>(device);
|
|
return (target->*_Function)();
|
|
}
|
|
|
|
// static template for a read8 stub function that calls through a given READ8_MEMBER
|
|
template<class _Class, UINT8 (_Class::*_Function)(address_space &, offs_t, UINT8)>
|
|
UINT8 devcb_stub(device_t *device, offs_t offset)
|
|
{
|
|
_Class *target = downcast<_Class *>(device);
|
|
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_stub16(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)
|
|
{
|
|
_Class *target = downcast<_Class *>(device);
|
|
(target->*_Function)(state);
|
|
}
|
|
|
|
// static template for a write8 stub function that calls through a given WRITE8_MEMBER
|
|
template<class _Class, void (_Class::*_Function)(address_space &, offs_t, UINT8, UINT8)>
|
|
void devcb_stub(device_t *device, offs_t offset, UINT8 data)
|
|
{
|
|
_Class *target = downcast<_Class *>(device);
|
|
(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_stub16(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 */
|
|
#define DEVCB_LINE(func) { DEVCB_TYPE_SELF, NULL, (func), NULL, NULL }
|
|
#define DEVCB_LINE_MEMBER(cls,memb) { DEVCB_TYPE_SELF, NULL, &devcb_line_stub<cls, &cls::memb>, NULL, NULL }
|
|
#define DEVCB_LINE_GND { DEVCB_TYPE_SELF, NULL, devcb_line_gnd_r, NULL, NULL }
|
|
#define DEVCB_LINE_VCC { DEVCB_TYPE_SELF, NULL, devcb_line_vcc_r, NULL, NULL }
|
|
#define DEVCB_HANDLER(func) { DEVCB_TYPE_SELF, NULL, NULL, (func), NULL }
|
|
#define DEVCB_MEMBER(cls,memb) { DEVCB_TYPE_SELF, NULL, NULL, &devcb_stub<cls, &cls::memb>, NULL }
|
|
|
|
/* line or read/write handlers for the driver device */
|
|
#define DEVCB_DRIVER_LINE_MEMBER(cls,memb) { DEVCB_TYPE_DRIVER, NULL, &devcb_line_stub<cls, &cls::memb>, NULL, NULL }
|
|
#define DEVCB_DRIVER_MEMBER(cls,memb) { DEVCB_TYPE_DRIVER, NULL, NULL, &devcb_stub<cls, &cls::memb>, NULL }
|
|
|
|
/* line or read/write handlers for another device */
|
|
#define DEVCB_DEVICE_LINE(tag,func) { DEVCB_TYPE_DEVICE, tag, (func), NULL, NULL }
|
|
#define DEVCB_DEVICE_LINE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, tag, &devcb_line_stub<cls, &cls::memb>, NULL, NULL }
|
|
#define DEVCB_DEVICE_HANDLER(tag,func) { DEVCB_TYPE_DEVICE, tag, NULL, (func), NULL }
|
|
#define DEVCB_DEVICE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, tag, NULL, &devcb_stub<cls, &cls::memb>, NULL }
|
|
|
|
/* read/write handlers for a given CPU's address space */
|
|
#define DEVCB_MEMORY_HANDLER(cpu,space,func) { DEVCB_TYPE_MEMORY(AS_##space), (cpu), NULL, NULL, (func) }
|
|
|
|
/* read handlers for an I/O port by tag */
|
|
#define DEVCB_INPUT_PORT(tag) { DEVCB_TYPE_INPUT, (tag), NULL, NULL, NULL }
|
|
|
|
/* write handlers for a CPU input line */
|
|
#define DEVCB_CPU_INPUT_LINE(tag,line) { DEVCB_TYPE_CPU_LINE(line), (tag), NULL, NULL, NULL }
|
|
|
|
|
|
/* macros for defining read_line/write_line functions */
|
|
#define READ_LINE_DEVICE_HANDLER(name) int name(ATTR_UNUSED device_t *device)
|
|
#define WRITE_LINE_DEVICE_HANDLER(name) void name(ATTR_UNUSED device_t *device, ATTR_UNUSED int state)
|
|
|
|
#define DECLARE_READ_LINE_MEMBER(name) int name()
|
|
#define READ_LINE_MEMBER(name) int name()
|
|
#define DECLARE_WRITE_LINE_MEMBER(name) void name(ATTR_UNUSED int state)
|
|
#define WRITE_LINE_MEMBER(name) void name(ATTR_UNUSED int state)
|
|
|
|
/* macros for inline device handler initialization */
|
|
|
|
#define MCFG_DEVICE_CONFIG_DEVCB_GENERIC(_access, _struct, _entry, _tag, _type, _linefunc, _devfunc, _spacefunc) \
|
|
MCFG_DEVICE_CONFIG_DATA32(_struct, _entry .type, DEVCB_TYPE_DEVICE) \
|
|
MCFG_DEVICE_CONFIG_DATAPTR(_struct, _entry .tag, _tag) \
|
|
MCFG_DEVICE_CONFIG_DATAPTR(_struct, _entry . _access ## line, _linefunc) \
|
|
MCFG_DEVICE_CONFIG_DATAPTR(_struct, _entry . _access ## device, _devfunc) \
|
|
MCFG_DEVICE_CONFIG_DATAPTR(_struct, _entry . _access ## space, _spacefunc)
|
|
|
|
#define MCFG_DEVICE_CONFIG_READ_LINE(_struct, _entry, _tag, _func) MCFG_DEVICE_CONFIG_DEVCB_GENERIC(read, _struct, _entry, _tag, DEVCB_TYPE_DEVICE, _func, NULL, NULL)
|
|
#define MCFG_DEVICE_CONFIG_WRITE_LINE(_struct, _entry, _tag, _func) MCFG_DEVICE_CONFIG_DEVCB_GENERIC(write, _struct, _entry, _tag, DEVCB_TYPE_DEVICE, _func, NULL, NULL)
|
|
|
|
#define MCFG_DEVICE_CONFIG_READ_HANDLER(_struct, _entry, _tag, _func) MCFG_DEVICE_CONFIG_DEVCB_GENERIC(read, _struct, _entry, _tag, DEVCB_TYPE_DEVICE, NULL, _func, NULL)
|
|
#define MCFG_DEVICE_CONFIG_WRITE_HANDLER(_struct, _entry, _tag, _func) MCFG_DEVICE_CONFIG_DEVCB_GENERIC(write, _struct, _entry, _tag, DEVCB_TYPE_DEVICE, NULL, _func, NULL)
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
TYPE DEFINITIONS
|
|
***************************************************************************/
|
|
|
|
/* forward declarations */
|
|
class device_config;
|
|
|
|
|
|
/* static structure used for device configuration when the desired callback type is a read_line_device_func */
|
|
typedef struct _devcb_read_line devcb_read_line;
|
|
struct _devcb_read_line
|
|
{
|
|
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 */
|
|
read8_device_func readdevice; /* read device function */
|
|
read8_space_func readspace; /* read space function */
|
|
};
|
|
|
|
typedef struct _devcb_resolved_read_line devcb_resolved_read_line;
|
|
struct _devcb_resolved_read_line
|
|
{
|
|
const void * target; /* target object */
|
|
read_line_device_func read; /* read line function */
|
|
const void * realtarget; /* real target object for stubs */
|
|
union
|
|
{
|
|
read8_device_func readdevice;
|
|
read8_space_func readspace;
|
|
} real; /* real read function for stubs */
|
|
};
|
|
|
|
|
|
/* static structure used for device configuration when the desired callback type is a write_line_device_func */
|
|
typedef struct _devcb_write_line devcb_write_line;
|
|
struct _devcb_write_line
|
|
{
|
|
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 */
|
|
write8_device_func writedevice; /* write device function */
|
|
write8_space_func writespace; /* write space function */
|
|
};
|
|
|
|
typedef struct _devcb_resolved_write_line devcb_resolved_write_line;
|
|
struct _devcb_resolved_write_line
|
|
{
|
|
const void * target; /* target object */
|
|
write_line_device_func write; /* write line function */
|
|
const void * realtarget; /* real target object for stubs */
|
|
union
|
|
{
|
|
write8_device_func writedevice;
|
|
write8_space_func writespace;
|
|
int writeline;
|
|
} real; /* real write function for stubs */
|
|
};
|
|
|
|
|
|
/* static structure used for device configuration when the desired callback type is a read8_device_func */
|
|
typedef struct _devcb_read8 devcb_read8;
|
|
struct _devcb_read8
|
|
{
|
|
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 */
|
|
read8_device_func readdevice; /* read device function */
|
|
read8_space_func readspace; /* read space function */
|
|
};
|
|
|
|
typedef struct _devcb_resolved_read8 devcb_resolved_read8;
|
|
struct _devcb_resolved_read8
|
|
{
|
|
const void * target; /* target object */
|
|
read8_device_func read; /* read function */
|
|
const void * realtarget; /* real target object for stubs */
|
|
union
|
|
{
|
|
read8_device_func readdevice;
|
|
read8_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 write8_device_func */
|
|
typedef struct _devcb_write8 devcb_write8;
|
|
struct _devcb_write8
|
|
{
|
|
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 */
|
|
write8_device_func writedevice; /* write device function */
|
|
write8_space_func writespace; /* write space function */
|
|
};
|
|
|
|
typedef struct _devcb_resolved_write8 devcb_resolved_write8;
|
|
struct _devcb_resolved_write8
|
|
{
|
|
const void * target; /* target object */
|
|
write8_device_func write; /* write function */
|
|
const void * realtarget; /* real target object for stubs */
|
|
union
|
|
{
|
|
write8_device_func writedevice;
|
|
write8_space_func writespace;
|
|
write_line_device_func writeline;
|
|
} real; /* real write function for stubs */
|
|
};
|
|
|
|
|
|
/* 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
|
|
***************************************************************************/
|
|
|
|
|
|
/* ----- static-to-live conversion ----- */
|
|
|
|
/* convert a static read line definition to a live definition */
|
|
void devcb_resolve_read_line(devcb_resolved_read_line *resolved, const devcb_read_line *config, device_t *device);
|
|
|
|
/* convert a static write line definition to a live definition */
|
|
void devcb_resolve_write_line(devcb_resolved_write_line *resolved, const devcb_write_line *config, device_t *device);
|
|
|
|
/* convert a static 8-bit read definition to a live definition */
|
|
void devcb_resolve_read8(devcb_resolved_read8 *resolved, const devcb_read8 *config, device_t *device);
|
|
|
|
/* 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);
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
INLINE FUNCTIONS
|
|
***************************************************************************/
|
|
|
|
/*-------------------------------------------------
|
|
devcb_call_read_line - call through a
|
|
resolved read_line handler
|
|
-------------------------------------------------*/
|
|
|
|
INLINE int devcb_call_read_line(const devcb_resolved_read_line *resolved)
|
|
{
|
|
return (resolved->read != NULL) ? (*resolved->read)((device_t *)resolved->target) : 0;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
devcb_call_read8 - call through a
|
|
resolved read8 handler
|
|
-------------------------------------------------*/
|
|
|
|
INLINE int devcb_call_read8(const devcb_resolved_read8 *resolved, offs_t offset)
|
|
{
|
|
return (resolved->read != NULL) ? (*resolved->read)((device_t *)resolved->target, offset) : 0;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
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
|
|
-------------------------------------------------*/
|
|
|
|
INLINE void devcb_call_write_line(const devcb_resolved_write_line *resolved, int state)
|
|
{
|
|
if (resolved->write != NULL)
|
|
(*resolved->write)((device_t *)resolved->target, state);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
devcb_call_write8 - call through a
|
|
resolved write8 handler
|
|
-------------------------------------------------*/
|
|
|
|
INLINE void devcb_call_write8(const devcb_resolved_write8 *resolved, offs_t offset, UINT8 data)
|
|
{
|
|
if (resolved->write != NULL)
|
|
(*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
|
|
-------------------------------------------------*/
|
|
|
|
INLINE READ_LINE_DEVICE_HANDLER( devcb_line_gnd_r )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
devcb_line_vcc_r - input tied to Vcc
|
|
-------------------------------------------------*/
|
|
|
|
INLINE READ_LINE_DEVICE_HANDLER( devcb_line_vcc_r )
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
#endif /* __DEVCB_H__ */
|