mirror of
https://github.com/holub/mame
synced 2025-05-08 07:11:42 +03:00

assumption that all device tags are unique. Specifically, the following no longer need to provide a device type: AM_DEVREAD/WRITE DEVCB_DEVICE_HANDLER devtag_get_device devtag_reset device_list_find_by_tag as well as several device interfaces that referenced other devices. Also fixed assertion due to overflow in the recent sound fix.
943 lines
26 KiB
C
943 lines
26 KiB
C
/***************************************************************************
|
|
|
|
devintrf.c
|
|
|
|
Device interface functions.
|
|
|
|
Copyright Nicola Salmoria and the MAME Team.
|
|
Visit http://mamedev.org for licensing and usage restrictions.
|
|
|
|
***************************************************************************/
|
|
|
|
#include "driver.h"
|
|
#include "cpuintrf.h"
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
CONSTANTS
|
|
***************************************************************************/
|
|
|
|
#define TEMP_STRING_POOL_ENTRIES 16
|
|
#define MAX_STRING_LENGTH 256
|
|
|
|
// ->started states
|
|
//
|
|
// Only 0 and 1 are externally visible in practice, making it a
|
|
// boolean //for external users
|
|
|
|
enum {
|
|
DEVICE_STOPPED = 0,
|
|
DEVICE_STARTED = 1,
|
|
DEVICE_STARTING = 2,
|
|
DEVICE_DELAYED = 3
|
|
};
|
|
|
|
|
|
/***************************************************************************
|
|
GLOBAL VARIABLES
|
|
***************************************************************************/
|
|
|
|
static char temp_string_pool[TEMP_STRING_POOL_ENTRIES][MAX_STRING_LENGTH];
|
|
static int temp_string_pool_index;
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
FUNCTION PROTOTYPES
|
|
***************************************************************************/
|
|
|
|
static void device_list_stop(running_machine *machine);
|
|
static void device_list_reset(running_machine *machine);
|
|
static void set_default_string(UINT32 state, char *buffer);
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
INLINE FUNCTIONS
|
|
***************************************************************************/
|
|
|
|
/*-------------------------------------------------
|
|
get_temp_string_buffer - return a pointer to
|
|
a temporary string buffer
|
|
-------------------------------------------------*/
|
|
|
|
static char *get_temp_string_buffer(void)
|
|
{
|
|
char *string = &temp_string_pool[temp_string_pool_index++ % TEMP_STRING_POOL_ENTRIES][0];
|
|
string[0] = 0;
|
|
return string;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_matches_type - does a device match
|
|
the provided type, taking wildcards into
|
|
effect?
|
|
-------------------------------------------------*/
|
|
|
|
INLINE int device_matches_type(const device_config *device, device_type type)
|
|
{
|
|
return (type == DEVICE_TYPE_WILDCARD) ? TRUE : (device->type == type);
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
DEVICE CONFIGURATION
|
|
***************************************************************************/
|
|
|
|
/*-------------------------------------------------
|
|
device_list_add - add a new device to the
|
|
end of a device list
|
|
-------------------------------------------------*/
|
|
|
|
device_config *device_list_add(device_config **listheadptr, const device_config *owner, device_type type, const char *tag, UINT32 clock)
|
|
{
|
|
device_config **devptr, **tempdevptr;
|
|
device_config *device, *tempdevice;
|
|
UINT32 configlen;
|
|
|
|
assert(listheadptr != NULL);
|
|
assert(type != NULL);
|
|
assert(tag != NULL);
|
|
|
|
/* find the end of the list, and ensure no duplicates along the way */
|
|
for (devptr = listheadptr; *devptr != NULL; devptr = &(*devptr)->next)
|
|
if (strcmp(tag, (*devptr)->tag) == 0)
|
|
fatalerror("Attempted to add duplicate device: type=%s tag=%s\n", device_get_name(*devptr), tag);
|
|
|
|
/* get the size of the inline config */
|
|
configlen = (UINT32)devtype_get_info_int(type, DEVINFO_INT_INLINE_CONFIG_BYTES);
|
|
|
|
/* allocate a new device */
|
|
device = malloc_or_die(sizeof(*device) + strlen(tag) + configlen);
|
|
|
|
/* populate device relationships */
|
|
device->next = NULL;
|
|
device->owner = (device_config *)owner;
|
|
device->typenext = NULL;
|
|
device->classnext = NULL;
|
|
|
|
/* populate device properties */
|
|
device->type = type;
|
|
device->devclass = devtype_get_info_int(type, DEVINFO_INT_CLASS);
|
|
device->set_info = (device_set_info_func)devtype_get_info_fct(type, DEVINFO_FCT_SET_INFO);
|
|
device->execute = NULL;
|
|
|
|
/* populate device configuration */
|
|
device->clock = clock;
|
|
device->static_config = NULL;
|
|
device->inline_config = (configlen == 0) ? NULL : (device->tag + strlen(tag) + 1);
|
|
|
|
/* ensure live fields are all cleared */
|
|
device->machine = NULL;
|
|
device->started = DEVICE_STOPPED;
|
|
device->token = NULL;
|
|
device->tokenbytes = 0;
|
|
device->region = NULL;
|
|
device->regionbytes = 0;
|
|
|
|
/* append the tag */
|
|
strcpy(device->tag, tag);
|
|
|
|
/* reset the inline_config to 0 */
|
|
if (configlen > 0)
|
|
memset(device->inline_config, 0, configlen);
|
|
|
|
/* fetch function pointers to the core functions */
|
|
|
|
/* before adding us to the global list, add us to the end of the type list */
|
|
tempdevice = (device_config *)device_list_first(*listheadptr, type);
|
|
for (tempdevptr = &tempdevice; *tempdevptr != NULL; tempdevptr = &(*tempdevptr)->typenext) ;
|
|
*tempdevptr = device;
|
|
|
|
/* and to the end of the class list */
|
|
tempdevice = (device_config *)device_list_class_first(*listheadptr, device->devclass);
|
|
for (tempdevptr = &tempdevice; *tempdevptr != NULL; tempdevptr = &(*tempdevptr)->classnext) ;
|
|
*tempdevptr = device;
|
|
|
|
/* link us to the end of the master list and return */
|
|
*devptr = device;
|
|
return device;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_list_remove - remove a device from a
|
|
device list
|
|
-------------------------------------------------*/
|
|
|
|
void device_list_remove(device_config **listheadptr, const char *tag)
|
|
{
|
|
device_config **devptr, **tempdevptr;
|
|
device_config *device, *tempdevice;
|
|
|
|
assert(listheadptr != NULL);
|
|
assert(tag != NULL);
|
|
|
|
/* find the device in the list */
|
|
for (devptr = listheadptr; *devptr != NULL; devptr = &(*devptr)->next)
|
|
if (strcmp(tag, (*devptr)->tag) == 0)
|
|
break;
|
|
device = *devptr;
|
|
if (device == NULL)
|
|
fatalerror("Attempted to remove non-existant device: tag=%s\n", tag);
|
|
|
|
/* before removing us from the global list, remove us from the type list */
|
|
tempdevice = (device_config *)device_list_first(*listheadptr, device->type);
|
|
for (tempdevptr = &tempdevice; *tempdevptr != device; tempdevptr = &(*tempdevptr)->typenext) ;
|
|
assert(*tempdevptr == device);
|
|
*tempdevptr = device->typenext;
|
|
|
|
/* and from the class list */
|
|
tempdevice = (device_config *)device_list_class_first(*listheadptr, device->devclass);
|
|
for (tempdevptr = &tempdevice; *tempdevptr != device; tempdevptr = &(*tempdevptr)->classnext) ;
|
|
assert(*tempdevptr == device);
|
|
*tempdevptr = device->classnext;
|
|
|
|
/* remove the device from the list */
|
|
*devptr = device->next;
|
|
|
|
/* free the device object */
|
|
free(device);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_build_tag - build a tag that combines
|
|
the device's name and the given tag
|
|
-------------------------------------------------*/
|
|
|
|
const char *device_build_tag(astring *dest, const device_config *device, const char *tag)
|
|
{
|
|
if (device != NULL)
|
|
{
|
|
astring_cpyc(dest, device->tag);
|
|
astring_catc(dest, ":");
|
|
astring_catc(dest, tag);
|
|
}
|
|
else
|
|
astring_cpyc(dest, tag);
|
|
return astring_c(dest);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_inherit_tag - build a tag with the same
|
|
device prefix as the source tag
|
|
-------------------------------------------------*/
|
|
|
|
const char *device_inherit_tag(astring *dest, const char *sourcetag, const char *tag)
|
|
{
|
|
const char *divider = strrchr(sourcetag, ':');
|
|
if (divider != NULL)
|
|
{
|
|
astring_cpych(dest, sourcetag, divider + 1 - sourcetag);
|
|
astring_catc(dest, tag);
|
|
}
|
|
else
|
|
astring_cpyc(dest, tag);
|
|
return astring_c(dest);
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
TYPE-BASED DEVICE ACCESS
|
|
***************************************************************************/
|
|
|
|
/*-------------------------------------------------
|
|
device_list_items - 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)
|
|
{
|
|
const device_config *curdev;
|
|
int count = 0;
|
|
|
|
/* locate all devices */
|
|
if (type == DEVICE_TYPE_WILDCARD)
|
|
{
|
|
for (curdev = listhead; curdev != NULL; curdev = curdev->next)
|
|
count++;
|
|
}
|
|
|
|
/* locate all devices of a given type */
|
|
else
|
|
{
|
|
for (curdev = listhead; curdev != NULL && curdev->type != type; curdev = curdev->next) ;
|
|
for ( ; curdev != NULL; curdev = curdev->typenext)
|
|
count++;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_list_first - return the first device
|
|
in the list of a given type;
|
|
DEVICE_TYPE_WILDCARD is allowed
|
|
-------------------------------------------------*/
|
|
|
|
const device_config *device_list_first(const device_config *listhead, device_type type)
|
|
{
|
|
const device_config *curdev;
|
|
|
|
/* first of any device type */
|
|
if (type == DEVICE_TYPE_WILDCARD)
|
|
return listhead;
|
|
|
|
/* first of a given type */
|
|
for (curdev = listhead; curdev != NULL && curdev->type != type; curdev = curdev->next) ;
|
|
return curdev;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_list_next - return the next device
|
|
in the list of a given type;
|
|
DEVICE_TYPE_WILDCARD is allowed
|
|
-------------------------------------------------*/
|
|
|
|
const device_config *device_list_next(const device_config *prevdevice, device_type type)
|
|
{
|
|
assert(prevdevice != NULL);
|
|
return (type == DEVICE_TYPE_WILDCARD) ? prevdevice->next : prevdevice->typenext;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_list_find_by_tag - 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, const char *tag)
|
|
{
|
|
const device_config *curdev;
|
|
|
|
assert(tag != NULL);
|
|
|
|
/* locate among all devices */
|
|
for (curdev = listhead; curdev != NULL; curdev = curdev->next)
|
|
if (strcmp(tag, curdev->tag) == 0)
|
|
return curdev;
|
|
|
|
/* fail */
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_list_index - 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)
|
|
{
|
|
const device_config *curdev;
|
|
int index = 0;
|
|
|
|
assert(tag != NULL);
|
|
|
|
/* locate among all devices */
|
|
if (type == DEVICE_TYPE_WILDCARD)
|
|
{
|
|
for (curdev = listhead; curdev != NULL; curdev = curdev->next)
|
|
{
|
|
if (strcmp(tag, curdev->tag) == 0)
|
|
return index;
|
|
index++;
|
|
}
|
|
}
|
|
|
|
/* locate among all devices of a given type */
|
|
else
|
|
{
|
|
for (curdev = listhead; curdev != NULL && curdev->type != type; curdev = curdev->next) ;
|
|
for ( ; curdev != NULL; curdev = curdev->typenext)
|
|
{
|
|
if (strcmp(tag, curdev->tag) == 0)
|
|
return index;
|
|
index++;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_list_find_by_index - retrieve a device
|
|
configuration based on a type and index
|
|
-------------------------------------------------*/
|
|
|
|
const device_config *device_list_find_by_index(const device_config *listhead, device_type type, int index)
|
|
{
|
|
const device_config *curdev;
|
|
|
|
/* locate among all devices */
|
|
if (type == DEVICE_TYPE_WILDCARD)
|
|
{
|
|
for (curdev = listhead; curdev != NULL; curdev = curdev->next)
|
|
if (index-- == 0)
|
|
return curdev;
|
|
}
|
|
|
|
/* locate among all devices of a given type */
|
|
else
|
|
{
|
|
for (curdev = listhead; curdev != NULL && curdev->type != type; curdev = curdev->next) ;
|
|
for ( ; curdev != NULL; curdev = curdev->typenext)
|
|
if (index-- == 0)
|
|
return curdev;
|
|
}
|
|
|
|
/* fail */
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
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 devclass)
|
|
{
|
|
const device_config *curdev;
|
|
int count = 0;
|
|
|
|
/* locate all devices of a given class */
|
|
for (curdev = listhead; curdev != NULL && curdev->devclass != devclass; curdev = curdev->next) ;
|
|
for ( ; curdev != NULL; curdev = curdev->classnext)
|
|
count++;
|
|
|
|
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 devclass)
|
|
{
|
|
const device_config *curdev;
|
|
|
|
/* first of a given class */
|
|
for (curdev = listhead; curdev != NULL && curdev->devclass != devclass; curdev = curdev->next) ;
|
|
return curdev;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
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 devclass)
|
|
{
|
|
assert(prevdevice != NULL);
|
|
return prevdevice->classnext;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
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 devclass, const char *tag)
|
|
{
|
|
const device_config *curdev;
|
|
int index = 0;
|
|
|
|
assert(tag != NULL);
|
|
|
|
/* locate among all devices of a given class */
|
|
for (curdev = listhead; curdev != NULL && curdev->devclass != devclass; curdev = curdev->next) ;
|
|
for ( ; curdev != NULL; curdev = curdev->classnext)
|
|
{
|
|
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 devclass, int index)
|
|
{
|
|
const device_config *curdev;
|
|
|
|
/* locate among all devices of a given class */
|
|
for (curdev = listhead; curdev != NULL && curdev->devclass != devclass; curdev = curdev->next) ;
|
|
for ( ; curdev != NULL; curdev = curdev->classnext)
|
|
if (index-- == 0)
|
|
return curdev;
|
|
|
|
/* fail */
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
LIVE DEVICE MANAGEMENT
|
|
***************************************************************************/
|
|
|
|
/*-------------------------------------------------
|
|
device_list_attach_machine - "attach" a
|
|
running_machine to its list of devices
|
|
-------------------------------------------------*/
|
|
|
|
void device_list_attach_machine(running_machine *machine)
|
|
{
|
|
device_config *device;
|
|
|
|
assert(machine != NULL);
|
|
|
|
/* iterate over devices and assign the machine to them */
|
|
for (device = (device_config *)machine->config->devicelist; device != NULL; device = device->next)
|
|
device->machine = machine;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_list_start - start the configured list
|
|
of devices for a machine
|
|
-------------------------------------------------*/
|
|
|
|
void device_list_start(running_machine *machine)
|
|
{
|
|
device_config *device;
|
|
int numstarted = 0;
|
|
int devcount = 0;
|
|
|
|
assert(machine != NULL);
|
|
|
|
/* add an exit callback for cleanup */
|
|
add_reset_callback(machine, device_list_reset);
|
|
add_exit_callback(machine, device_list_stop);
|
|
|
|
/* iterate over devices and allocate memory for them */
|
|
for (device = (device_config *)machine->config->devicelist; device != NULL; device = device->next)
|
|
{
|
|
assert(!device->started);
|
|
assert(device->machine == machine);
|
|
assert(device->token == NULL);
|
|
assert(device->type != NULL);
|
|
|
|
devcount++;
|
|
|
|
/* get the size of the token data; we do it directly because we can't call device_get_info_* with no token */
|
|
device->tokenbytes = device_get_info_int(device, DEVINFO_INT_TOKEN_BYTES);
|
|
if (device->tokenbytes == 0)
|
|
fatalerror("Device %s specifies a 0 token length!\n", device_get_name(device));
|
|
|
|
/* allocate memory for the token */
|
|
device->token = malloc_or_die(device->tokenbytes);
|
|
memset(device->token, 0, device->tokenbytes);
|
|
|
|
/* fill in the remaining runtime fields */
|
|
device->execute = (device_execute_func)device_get_info_fct(device, DEVINFO_FCT_EXECUTE);
|
|
device->machine = machine;
|
|
device->region = memory_region(machine, device->tag);
|
|
device->regionbytes = memory_region_length(machine, device->tag);
|
|
}
|
|
|
|
/* iterate until we've started everything */
|
|
while (numstarted < devcount)
|
|
{
|
|
int prevstarted = numstarted;
|
|
|
|
/* iterate over devices and start them */
|
|
for (device = (device_config *)machine->config->devicelist; device != NULL; device = device->next)
|
|
{
|
|
device_start_func start = (device_start_func)device_get_info_fct(device, DEVINFO_FCT_START);
|
|
assert(start != NULL);
|
|
|
|
if (!device->started)
|
|
{
|
|
device->started = DEVICE_STARTING;
|
|
(*start)(device);
|
|
|
|
/* if the start was delayed, move back to the stopped state, otherwise count it */
|
|
if (device->started == DEVICE_DELAYED)
|
|
device->started = DEVICE_STOPPED;
|
|
else
|
|
{
|
|
device->started = DEVICE_STARTED;
|
|
numstarted++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* if we didn't start anything new, we're in trouble */
|
|
if (numstarted == prevstarted)
|
|
fatalerror("Circular dependency in device startup; unable to start %d/%d devices\n", devcount - numstarted, devcount);
|
|
}
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_delay_init - delay the startup of a
|
|
given device for dependency reasons
|
|
-------------------------------------------------*/
|
|
|
|
void device_delay_init(const device_config *device)
|
|
{
|
|
if (device->started != DEVICE_STARTING && device->started != DEVICE_DELAYED)
|
|
fatalerror("Error: Calling device_delay_init on a device not in the process of starting.");
|
|
((device_config *)device)->started = DEVICE_DELAYED;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_list_stop - stop the configured list
|
|
of devices for a machine
|
|
-------------------------------------------------*/
|
|
|
|
static void device_list_stop(running_machine *machine)
|
|
{
|
|
device_config *device;
|
|
|
|
assert(machine != NULL);
|
|
|
|
/* iterate over devices and stop them */
|
|
for (device = (device_config *)machine->config->devicelist; device != NULL; device = device->next)
|
|
{
|
|
device_stop_func stop = (device_stop_func)device_get_info_fct(device, DEVINFO_FCT_STOP);
|
|
|
|
assert(device->token != NULL);
|
|
assert(device->type != NULL);
|
|
|
|
/* if we have a stop function, call it */
|
|
if (stop != NULL)
|
|
(*stop)(device);
|
|
|
|
/* free allocated memory for the token */
|
|
if (device->token != NULL)
|
|
free(device->token);
|
|
|
|
/* reset all runtime fields */
|
|
device->token = NULL;
|
|
device->tokenbytes = 0;
|
|
device->machine = NULL;
|
|
device->region = NULL;
|
|
device->regionbytes = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_list_reset - reset the configured list
|
|
of devices for a machine
|
|
-------------------------------------------------*/
|
|
|
|
static void device_list_reset(running_machine *machine)
|
|
{
|
|
const device_config *device;
|
|
|
|
assert(machine != NULL);
|
|
|
|
/* iterate over devices and stop them */
|
|
for (device = (device_config *)machine->config->devicelist; device != NULL; device = device->next)
|
|
device_reset(device);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_reset - reset a device based on an
|
|
allocated device_config
|
|
-------------------------------------------------*/
|
|
|
|
void device_reset(const device_config *device)
|
|
{
|
|
device_reset_func reset;
|
|
|
|
assert(device != NULL);
|
|
assert(device->token != NULL);
|
|
assert(device->type != NULL);
|
|
|
|
/* if we have a reset function, call it */
|
|
reset = (device_reset_func)device_get_info_fct(device, DEVINFO_FCT_RESET);
|
|
if (reset != NULL)
|
|
(*reset)(device);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_set_clock - change the clock on a
|
|
device
|
|
-------------------------------------------------*/
|
|
|
|
void device_set_clock(const device_config *device, UINT32 clock)
|
|
{
|
|
device_config *devicerw = (device_config *)device;
|
|
|
|
/* not much for now */
|
|
devicerw->clock = clock;
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
DEVICE INFORMATION GETTERS
|
|
***************************************************************************/
|
|
|
|
/*-------------------------------------------------
|
|
device_get_info_int - return an integer state
|
|
value from an allocated device
|
|
-------------------------------------------------*/
|
|
|
|
INT64 device_get_info_int(const device_config *device, UINT32 state)
|
|
{
|
|
deviceinfo info;
|
|
|
|
assert(device != NULL);
|
|
assert(device->type != NULL);
|
|
assert(state >= DEVINFO_INT_FIRST && state <= DEVINFO_INT_LAST);
|
|
|
|
/* retrieve the value */
|
|
info.i = 0;
|
|
(*device->type)(device, state, &info);
|
|
return info.i;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_get_info_ptr - return a pointer state
|
|
value from an allocated device
|
|
-------------------------------------------------*/
|
|
|
|
void *device_get_info_ptr(const device_config *device, UINT32 state)
|
|
{
|
|
deviceinfo info;
|
|
|
|
assert(device != NULL);
|
|
assert(device->type != NULL);
|
|
assert(state >= DEVINFO_PTR_FIRST && state <= DEVINFO_PTR_LAST);
|
|
|
|
/* retrieve the value */
|
|
info.p = NULL;
|
|
(*device->type)(device, state, &info);
|
|
return info.p;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_get_info_fct - return a function
|
|
pointer state value from an allocated device
|
|
-------------------------------------------------*/
|
|
|
|
genf *device_get_info_fct(const device_config *device, UINT32 state)
|
|
{
|
|
deviceinfo info;
|
|
|
|
assert(device != NULL);
|
|
assert(device->type != NULL);
|
|
assert(state >= DEVINFO_FCT_FIRST && state <= DEVINFO_FCT_LAST);
|
|
|
|
/* retrieve the value */
|
|
info.f = 0;
|
|
(*device->type)(device, state, &info);
|
|
return info.f;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_get_info_string - return a string value
|
|
from an allocated device
|
|
-------------------------------------------------*/
|
|
|
|
const char *device_get_info_string(const device_config *device, UINT32 state)
|
|
{
|
|
deviceinfo info;
|
|
|
|
assert(device != NULL);
|
|
assert(device->type != NULL);
|
|
assert(state >= DEVINFO_STR_FIRST && state <= DEVINFO_STR_LAST);
|
|
|
|
/* retrieve the value */
|
|
info.s = get_temp_string_buffer();
|
|
(*device->type)(device, state, &info);
|
|
if (info.s[0] == 0)
|
|
set_default_string(state, info.s);
|
|
return info.s;
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
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, state, &info);
|
|
return info.i;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
devtype_get_info_int - return a function
|
|
pointer from a device type (does not need to
|
|
be allocated)
|
|
-------------------------------------------------*/
|
|
|
|
genf *devtype_get_info_fct(device_type type, UINT32 state)
|
|
{
|
|
deviceinfo info;
|
|
|
|
assert(type != NULL);
|
|
assert(state >= DEVINFO_FCT_FIRST && state <= DEVINFO_FCT_LAST);
|
|
|
|
/* retrieve the value */
|
|
info.f = 0;
|
|
(*type)(NULL, state, &info);
|
|
return info.f;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
devtype_get_info_string - 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)
|
|
{
|
|
deviceinfo info;
|
|
|
|
assert(type != NULL);
|
|
assert(state >= DEVINFO_STR_FIRST && state <= DEVINFO_STR_LAST);
|
|
|
|
/* retrieve the value */
|
|
info.s = get_temp_string_buffer();
|
|
(*type)(NULL, state, &info);
|
|
if (info.s[0] == 0)
|
|
set_default_string(state, info.s);
|
|
return info.s;
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
DEVICE INFORMATION SETTERS
|
|
***************************************************************************/
|
|
|
|
/*-------------------------------------------------
|
|
device_set_info_int - set an integer state
|
|
value for an allocated device
|
|
-------------------------------------------------*/
|
|
|
|
void device_set_info_int(const device_config *device, UINT32 state, INT64 data)
|
|
{
|
|
deviceinfo info;
|
|
|
|
assert(device != NULL);
|
|
assert(device->token != NULL);
|
|
assert(device->type != NULL);
|
|
assert(state >= DEVINFO_INT_FIRST && state <= DEVINFO_INT_LAST);
|
|
|
|
/* set the value */
|
|
info.i = data;
|
|
(*device->set_info)(device, state, &info);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_set_info_ptr - set a pointer state
|
|
value for an allocated device
|
|
-------------------------------------------------*/
|
|
|
|
void device_set_info_ptr(const device_config *device, UINT32 state, void *data)
|
|
{
|
|
deviceinfo info;
|
|
|
|
assert(device != NULL);
|
|
assert(device->token != NULL);
|
|
assert(device->type != NULL);
|
|
assert(state >= DEVINFO_PTR_FIRST && state <= DEVINFO_PTR_LAST);
|
|
|
|
/* set the value */
|
|
info.p = data;
|
|
(*device->set_info)(device, state, &info);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
device_set_info_fct - set a function pointer
|
|
state value for an allocated device
|
|
-------------------------------------------------*/
|
|
|
|
void device_set_info_fct(const device_config *device, UINT32 state, genf *data)
|
|
{
|
|
deviceinfo info;
|
|
|
|
assert(device != NULL);
|
|
assert(device->token != NULL);
|
|
assert(device->type != NULL);
|
|
assert(state >= DEVINFO_FCT_FIRST && state <= DEVINFO_FCT_LAST);
|
|
|
|
/* set the value */
|
|
info.f = data;
|
|
(*device->set_info)(device, state, &info);
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
DEVICE INFORMATION SETTERS
|
|
***************************************************************************/
|
|
|
|
/*-------------------------------------------------
|
|
set_default_string - compute a default string
|
|
if none is provided
|
|
-------------------------------------------------*/
|
|
|
|
static void set_default_string(UINT32 state, char *buffer)
|
|
{
|
|
switch (state)
|
|
{
|
|
case DEVINFO_STR_NAME: strcpy(buffer, "Custom"); break;
|
|
case DEVINFO_STR_FAMILY: strcpy(buffer, "Custom"); break;
|
|
case DEVINFO_STR_VERSION: strcpy(buffer, "1.0"); break;
|
|
case DEVINFO_STR_SOURCE_FILE: strcpy(buffer, __FILE__); break;
|
|
case DEVINFO_STR_CREDITS: strcpy(buffer, "Copyright Nicola Salmoria and the MAME Team"); break;
|
|
}
|
|
}
|