Added macros to define device functions. Updated existing devices

to use the macros.

Added the concept of device classes. Devices specify their class
in their get_info function. Classes can be used to walk through
devices at a more general level than their type. Functions have
been added to iterate through devices by class just as you can
by type.

Removed some unused fields from device_config.
This commit is contained in:
Aaron Giles 2008-03-01 08:41:56 +00:00
parent 2fba8bdb8a
commit b8a64773fd
9 changed files with 295 additions and 69 deletions

View File

@ -344,29 +344,33 @@ static int bitmap_to_chars(bitmap_t *bitmap, render_font *font)
break;
}
/* print info */
// printf(" Character %X - width = %d\n", chstart, colend - colstart + 1);
/* allocate a bitmap */
ch->bitmap = bitmap_alloc(colend - colstart + 1, font->height, BITMAP_FORMAT_ARGB32);
if (ch->bitmap == NULL)
// skip char which code is already registered
if (ch->width <= 0)
{
fprintf(stderr, "Error allocating character bitmap (%dx%d)\n", colend - colstart + 1, font->height);
continue;
/* print info */
// printf(" Character %X - width = %d\n", chstart, colend - colstart + 1);
/* allocate a bitmap */
ch->bitmap = bitmap_alloc(colend - colstart + 1, font->height, BITMAP_FORMAT_ARGB32);
if (ch->bitmap == NULL)
{
fprintf(stderr, "Error allocating character bitmap (%dx%d)\n", colend - colstart + 1, font->height);
continue;
}
/* plot the character */
for (y = rowstart; y <= rowend; y++)
for (x = colstart; x <= colend; x++)
*BITMAP_ADDR32(ch->bitmap, y - rowstart, x - colstart) = pixel_is_set(bitmap, y, x) ? 0xffffffff : 0x00000000;
/* set the character parameters */
ch->width = colend - colstart + 1;
ch->xoffs = 0;
ch->yoffs = font->yoffs;
ch->bmwidth = ch->bitmap->width;
ch->bmheight = ch->bitmap->height;
}
/* plot the character */
for (y = rowstart; y <= rowend; y++)
for (x = colstart; x <= colend; x++)
*BITMAP_ADDR32(ch->bitmap, y - rowstart, x - colstart) = pixel_is_set(bitmap, y, x) ? 0xffffffff : 0x00000000;
/* set the character parameters */
ch->width = colend - colstart + 1;
ch->xoffs = 0;
ch->yoffs = font->yoffs;
ch->bmwidth = ch->bitmap->width;
ch->bmheight = ch->bitmap->height;
/* next character */
chstart++;
colstart = colend + 1;

View File

@ -83,6 +83,7 @@ device_config *device_list_add(device_config **listheadptr, device_type type, co
{
device_config **devptr;
device_config *device;
UINT32 configlen;
deviceinfo info;
assert(listheadptr != NULL);
@ -95,23 +96,23 @@ device_config *device_list_add(device_config **listheadptr, device_type type, co
fatalerror("Attempted to add duplicate device: type=%s tag=%s\n", devtype_name(type), tag);
/* get the size of the inline config */
info.i = 0;
(*type)(NULL, NULL, DEVINFO_INT_INLINE_CONFIG_BYTES, &info);
configlen = (UINT32)devtype_get_info_int(type, DEVINFO_INT_INLINE_CONFIG_BYTES);
/* allocate a new device */
device = malloc_or_die(sizeof(*device) + strlen(tag) + info.i);
device = malloc_or_die(sizeof(*device) + strlen(tag) + configlen);
/* populate all fields */
device->next = NULL;
device->type = type;
device->class = devtype_get_info_int(type, DEVINFO_INT_CLASS);
device->static_config = NULL;
device->inline_config = (info.i == 0) ? NULL : (device->tag + strlen(tag) + 1);
device->inline_config = (configlen == 0) ? NULL : (device->tag + strlen(tag) + 1);
device->token = NULL;
strcpy(device->tag, tag);
/* reset the inline_config to 0 */
if (info.i > 0)
memset(device->inline_config, 0, info.i);
if (configlen > 0)
memset(device->inline_config, 0, configlen);
/* fetch function pointers to the core functions */
info.set_info = NULL;
@ -166,6 +167,11 @@ void device_list_remove(device_config **listheadptr, device_type type, const cha
}
/***************************************************************************
TYPE-BASED DEVICE ACCESS
***************************************************************************/
/*-------------------------------------------------
device_list_items - return the number of
items of a given type; DEVICE_TYPE_WILDCARD
@ -246,12 +252,6 @@ const device_config *device_list_find_by_tag(const device_config *listhead, devi
}
/***************************************************************************
INDEX-BASED DEVICE ACCESS
***************************************************************************/
/*-------------------------------------------------
device_list_index - return the index of a
device based on its type and tag;
@ -296,6 +296,131 @@ const device_config *device_list_find_by_index(const device_config *listhead, de
/***************************************************************************
CLASS-BASED DEVICE ACCESS
***************************************************************************/
/*-------------------------------------------------
device_list_class_items - return the number of
items of a given class
-------------------------------------------------*/
int device_list_class_items(const device_config *listhead, device_class class)
{
const device_config *curdev;
int count = 0;
/* locate all devices */
for (curdev = listhead; curdev != NULL; curdev = curdev->next)
count += (curdev->class == class);
return count;
}
/*-------------------------------------------------
device_list_class_first - return the first
device in the list of a given class
-------------------------------------------------*/
const device_config *device_list_class_first(const device_config *listhead, device_class class)
{
const device_config *curdev;
/* scan forward starting with the list head */
for (curdev = listhead; curdev != NULL; curdev = curdev->next)
if (curdev->class == class)
return curdev;
return NULL;
}
/*-------------------------------------------------
device_list_class_next - return the next
device in the list of a given class
-------------------------------------------------*/
const device_config *device_list_class_next(const device_config *prevdevice, device_class class)
{
const device_config *curdev;
assert(prevdevice != NULL);
/* scan forward starting with the item after the previous one */
for (curdev = prevdevice->next; curdev != NULL; curdev = curdev->next)
if (curdev->class == class)
return curdev;
return NULL;
}
/*-------------------------------------------------
device_list_class_find_by_tag - retrieve a
device configuration based on a class and tag
-------------------------------------------------*/
const device_config *device_list_class_find_by_tag(const device_config *listhead, device_class class, const char *tag)
{
const device_config *curdev;
assert(tag != NULL);
/* find the device in the list */
for (curdev = listhead; curdev != NULL; curdev = curdev->next)
if (curdev->class == class && strcmp(tag, curdev->tag) == 0)
return curdev;
/* fail */
return NULL;
}
/*-------------------------------------------------
device_list_class_index - return the index of a
device based on its class and tag
-------------------------------------------------*/
int device_list_class_index(const device_config *listhead, device_class class, const char *tag)
{
const device_config *curdev;
int index = 0;
/* locate all devices */
for (curdev = listhead; curdev != NULL; curdev = curdev->next)
if (curdev->class == class)
{
if (strcmp(tag, curdev->tag) == 0)
return index;
index++;
}
return -1;
}
/*-------------------------------------------------
device_list_class_find_by_index - retrieve a
device configuration based on a class and
index
-------------------------------------------------*/
const device_config *device_list_class_find_by_index(const device_config *listhead, device_class class, int index)
{
const device_config *curdev;
/* find the device in the list */
for (curdev = listhead; curdev != NULL; curdev = curdev->next)
if (curdev->class == class && index-- == 0)
return curdev;
/* fail */
return NULL;
}
/***************************************************************************
LIVE DEVICE MANAGEMENT
***************************************************************************/
@ -561,6 +686,31 @@ const char *devtag_get_info_string(running_machine *machine, device_type type, c
}
/***************************************************************************
DEVICE TYPE INFORMATION SETTERS
***************************************************************************/
/*-------------------------------------------------
devtype_get_info_int - return an integer value
from a device type (does not need to be
allocated)
-------------------------------------------------*/
INT64 devtype_get_info_int(device_type type, UINT32 state)
{
deviceinfo info;
assert(type != NULL);
assert(state >= DEVINFO_INT_FIRST && state <= DEVINFO_INT_LAST);
/* retrieve the value */
info.i = 0;
(*type)(NULL, NULL, state, &info);
return info.i;
}
/*-------------------------------------------------
devtype_get_info_string - return a string value
from a device type (does not need to be

View File

@ -21,6 +21,20 @@
CONSTANTS
***************************************************************************/
/* device classes */
enum _device_class
{
DEVICE_CLASS_GENERAL = 0, /* default class for general devices */
DEVICE_CLASS_PERIPHERAL, /* peripheral devices: PIAs, timers, etc. */
DEVICE_CLASS_AUDIO, /* audio devices (not sound chips), including speakers */
DEVICE_CLASS_VIDEO, /* video devices, including screens */
DEVICE_CLASS_CPU_CHIP, /* CPU chips; only CPU cores should return this class */
DEVICE_CLASS_SOUND_CHIP, /* sound chips; only sound cores should return this class */
DEVICE_CLASS_OTHER /* anything else (the list may expand in the future) */
};
typedef enum _device_class device_class;
/* useful in device_list functions for scanning through all devices */
#define DEVICE_TYPE_WILDCARD NULL
@ -32,6 +46,7 @@ enum
DEVINFO_INT_FIRST = 0x00000,
DEVINFO_INT_INLINE_CONFIG_BYTES = DEVINFO_INT_FIRST,/* R/O: bytes of inline configuration */
DEVINFO_INT_CLASS, /* R/O: the device's class */
DEVINFO_INT_DEVICE_SPECIFIC = 0x08000, /* R/W: device-specific values start here */
@ -72,6 +87,32 @@ enum
/***************************************************************************
MACROS
***************************************************************************/
#define DEVICE_GET_INFO_NAME(name) device_get_info_##name
#define DEVICE_GET_INFO(name) void DEVICE_GET_INFO_NAME(name)(running_machine *machine, void *token, UINT32 state, deviceinfo *info)
#define DEVICE_GET_INFO_CALL(name) DEVICE_GET_INFO_NAME(name)(machine, token, state, info)
#define DEVICE_SET_INFO_NAME(name) device_set_info_##name
#define DEVICE_SET_INFO(name) void DEVICE_SET_INFO_NAME(name)(running_machine *machine, void *token, UINT32 state, const deviceinfo *info)
#define DEVICE_SET_INFO_CALL(name) DEVICE_SET_INFO_NAME(name)(machine, token, state, info)
#define DEVICE_START_NAME(name) device_start_##name
#define DEVICE_START(name) void *DEVICE_START_NAME(name)(running_machine *machine, const char *tag, const void *static_config, const void *inline_config)
#define DEVICE_START_CALL(name) DEVICE_START_NAME(name)(machine, tag, static_config, inline_config)
#define DEVICE_STOP_NAME(name) device_stop_##name
#define DEVICE_STOP(name) void DEVICE_STOP_NAME(name)(running_machine *machine, void *token)
#define DEVICE_STOP_CALL(name) DEVICE_STOP_NAME(name)(machine, token)
#define DEVICE_RESET_NAME(name) device_reset_##name
#define DEVICE_RESET(name) void DEVICE_RESET_NAME(name)(running_machine *machine, void *token)
#define DEVICE_RESET_CALL(name) DEVICE_RESET_NAME(name)(machine, token)
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
@ -113,8 +154,7 @@ struct _device_config
{
device_config * next; /* next device */
device_type type; /* device type */
UINT32 flags; /* device flags */
UINT32 clock; /* device clock */
device_class class; /* device class */
device_set_info_func set_info; /* quick pointer to set_info callback */
device_start_func start; /* quick pointer to start callback */
device_stop_func stop; /* quick pointer to stop callback */
@ -140,6 +180,10 @@ device_config *device_list_add(device_config **listheadptr, device_type type, co
/* remove a device from a device list */
void device_list_remove(device_config **listheadptr, device_type type, const char *tag);
/* ----- type-based device access ----- */
/* return the number of items of a given type; DEVICE_TYPE_WILDCARD is allowed */
int device_list_items(const device_config *listhead, device_type type);
@ -152,10 +196,6 @@ const device_config *device_list_next(const device_config *prevdevice, device_ty
/* retrieve a device configuration based on a type and tag; DEVICE_TYPE_WILDCARD is allowed */
const device_config *device_list_find_by_tag(const device_config *listhead, device_type type, const char *tag);
/* ----- index-based device access (avoid if possible) ----- */
/* return the index of a device based on its type and tag; DEVICE_TYPE_WILDCARD is allowed */
int device_list_index(const device_config *listhead, device_type type, const char *tag);
@ -164,6 +204,28 @@ const device_config *device_list_find_by_index(const device_config *listhead, de
/* ----- class-based device access ----- */
/* return the number of items of a given class */
int device_list_class_items(const device_config *listhead, device_class class);
/* return the first device in the list of a given class */
const device_config *device_list_class_first(const device_config *listhead, device_class class);
/* return the next device in the list of a given class */
const device_config *device_list_class_next(const device_config *prevdevice, device_class class);
/* retrieve a device configuration based on a class and tag */
const device_config *device_list_class_find_by_tag(const device_config *listhead, device_class class, const char *tag);
/* return the index of a device based on its class and tag */
int device_list_class_index(const device_config *listhead, device_class class, const char *tag);
/* retrieve a device configuration based on a class and index */
const device_config *device_list_class_find_by_index(const device_config *listhead, device_class class, int index);
/* ----- live device management ----- */
/* start the configured list of devices for a machine */
@ -202,6 +264,13 @@ genf *devtag_get_info_fct(running_machine *machine, device_type type, const char
const char *device_get_info_string(running_machine *machine, const device_config *config, UINT32 state);
const char *devtag_get_info_string(running_machine *machine, device_type type, const char *tag, UINT32 state);
/* ----- device type information getters ----- */
/* return an integer value from a device type (does not need to be allocated) */
INT64 devtype_get_info_int(device_type type, UINT32 state);
/* return a string value from a device type (does not need to be allocated) */
const char *devtype_get_info_string(device_type type, UINT32 state);

View File

@ -785,7 +785,7 @@ static void mixer_update(void *param, stream_sample_t **inputs, stream_sample_t
for a speaker
-------------------------------------------------*/
static void *speaker_output_start(running_machine *machine, const char *tag, const void *static_config, const void *inline_config)
static DEVICE_START( speaker_output )
{
speaker_info *info;
@ -805,7 +805,7 @@ static void *speaker_output_start(running_machine *machine, const char *tag, con
for a speaker
-------------------------------------------------*/
static void speaker_output_stop(running_machine *machine, void *token)
static DEVICE_STOP( speaker_output )
{
#ifdef MAME_DEBUG
speaker_info *info = token;
@ -822,7 +822,7 @@ static void speaker_output_stop(running_machine *machine, void *token)
callback
-------------------------------------------------*/
static void speaker_output_set_info(running_machine *machine, void *token, UINT32 state, const deviceinfo *info)
static DEVICE_SET_INFO( speaker_output )
{
switch (state)
{
@ -836,17 +836,18 @@ static void speaker_output_set_info(running_machine *machine, void *token, UINT3
callback
-------------------------------------------------*/
void speaker_output_get_info(running_machine *machine, void *token, UINT32 state, deviceinfo *info)
DEVICE_GET_INFO( speaker_output )
{
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(speaker_config); break;
case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_AUDIO; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_SET_INFO: info->set_info = speaker_output_set_info;break;
case DEVINFO_FCT_START: info->start = speaker_output_start; break;
case DEVINFO_FCT_STOP: info->stop = speaker_output_stop; break;
case DEVINFO_FCT_SET_INFO: info->set_info = DEVICE_SET_INFO_NAME(speaker_output); break;
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(speaker_output); break;
case DEVINFO_FCT_STOP: info->stop = DEVICE_STOP_NAME(speaker_output); break;
case DEVINFO_FCT_RESET: /* Nothing */ break;
/* --- the following bits of info are returned as NULL-terminated strings --- */

View File

@ -101,8 +101,8 @@ int sound_find_sndnum_by_tag(const char *tag);
/* ----- sound speaker device interface ----- */
/* device get info callback */
#define SPEAKER_OUTPUT speaker_output_get_info
void speaker_output_get_info(running_machine *machine, void *token, UINT32 state, deviceinfo *info);
#define SPEAKER_OUTPUT DEVICE_GET_INFO_NAME(speaker_output)
DEVICE_GET_INFO( speaker_output );
#endif /* __SOUND_H__ */

View File

@ -1056,7 +1056,7 @@ attotime video_screen_get_frame_period(int scrnum)
for a video screen
-------------------------------------------------*/
static void *video_screen_start(running_machine *machine, const char *tag, const void *static_config, const void *inline_config)
static DEVICE_START( video_screen )
{
int scrindex = device_list_index(machine->config->devicelist, VIDEO_SCREEN, tag);
return &machine->screen[scrindex];
@ -1068,7 +1068,7 @@ static void *video_screen_start(running_machine *machine, const char *tag, const
callback
-------------------------------------------------*/
static void video_screen_set_info(running_machine *machine, void *token, UINT32 state, const deviceinfo *info)
static DEVICE_SET_INFO( video_screen )
{
switch (state)
{
@ -1082,16 +1082,17 @@ static void video_screen_set_info(running_machine *machine, void *token, UINT32
callback
-------------------------------------------------*/
void video_screen_get_info(running_machine *machine, void *token, UINT32 state, deviceinfo *info)
DEVICE_GET_INFO( video_screen )
{
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(screen_config); break;
case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_VIDEO; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_SET_INFO: info->set_info = video_screen_set_info;break;
case DEVINFO_FCT_START: info->start = video_screen_start; break;
case DEVINFO_FCT_SET_INFO: info->set_info = DEVICE_SET_INFO_NAME(video_screen); break;
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(video_screen); break;
case DEVINFO_FCT_STOP: /* Nothing */ break;
case DEVINFO_FCT_RESET: /* Nothing */ break;

View File

@ -141,8 +141,8 @@ int video_screen_exists(int scrnum);
/* ----- video screen device interface ----- */
/* device get info callback */
#define VIDEO_SCREEN video_screen_get_info
void video_screen_get_info(running_machine *machine, void *token, UINT32 state, deviceinfo *info);
#define VIDEO_SCREEN DEVICE_GET_INFO_NAME(video_screen)
DEVICE_GET_INFO( video_screen );

View File

@ -662,18 +662,18 @@ static void *common_start(running_machine *machine, const char *tag, const void
return mc6845;
}
static void *mc6845_start(running_machine *machine, const char *tag, const void *static_config, const void *inline_config)
static DEVICE_START( mc6845 )
{
return common_start(machine, tag, static_config, inline_config, TYPE_MC6845);
}
static void *r6545_start(running_machine *machine, const char *tag, const void *static_config, const void *inline_config)
static DEVICE_START( r6545 )
{
return common_start(machine, tag, static_config, inline_config, TYPE_R6545);
}
static void mc6845_reset(running_machine *machine, void *token)
static DEVICE_RESET( mc6845 )
{
mc6845_t *mc6845 = token;
@ -692,7 +692,7 @@ static void mc6845_reset(running_machine *machine, void *token)
}
static void mc6845_set_info(running_machine *machine, void *token, UINT32 state, const deviceinfo *info)
static DEVICE_SET_INFO( mc6845 )
{
switch (state)
{
@ -701,18 +701,19 @@ static void mc6845_set_info(running_machine *machine, void *token, UINT32 state,
}
void mc6845_get_info(running_machine *machine, void *token, UINT32 state, deviceinfo *info)
DEVICE_GET_INFO( mc6845 )
{
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_SET_INFO: info->set_info = mc6845_set_info; break;
case DEVINFO_FCT_START: info->start = mc6845_start; break;
case DEVINFO_FCT_SET_INFO: info->set_info = DEVICE_SET_INFO_NAME(mc6845); break;
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(mc6845);break;
case DEVINFO_FCT_STOP: /* Nothing */ break;
case DEVINFO_FCT_RESET: info->reset = mc6845_reset; break;
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(mc6845);break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: info->s = "MC6845"; break;
@ -724,7 +725,7 @@ void mc6845_get_info(running_machine *machine, void *token, UINT32 state, device
}
void r6545_get_info(running_machine *machine, void *token, UINT32 state, deviceinfo *info)
DEVICE_GET_INFO( r6545 )
{
switch (state)
{
@ -732,8 +733,8 @@ void r6545_get_info(running_machine *machine, void *token, UINT32 state, devicei
case DEVINFO_STR_NAME: info->s = "R6545"; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_START: info->start = r6545_start; break;
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(r6545); break;
default: mc6845_get_info(machine, token, state, info); break;
default: DEVICE_GET_INFO_CALL(mc6845); break;
}
}

View File

@ -14,8 +14,8 @@
typedef struct _mc6845_t mc6845_t;
typedef struct _mc6845_interface mc6845_interface;
#define MC6845 mc6845_get_info
#define R6545 r6545_get_info
#define MC6845 DEVICE_GET_INFO_NAME(mc6845)
#define R6545 DEVICE_GET_INFO_NAME(r6545)
/* callback definitions */
@ -77,8 +77,8 @@ struct _mc6845_interface
/* device interface */
void mc6845_get_info(running_machine *machine, void *token, UINT32 state, deviceinfo *info);
void r6545_get_info(running_machine *machine, void *token, UINT32 state, deviceinfo *info);
DEVICE_GET_INFO( mc6845 );
DEVICE_GET_INFO( r6545 );
/* select one of the registers for reading or writing */
void mc6845_address_w(mc6845_t *mc6845, UINT8 data);