/*************************************************************************** devintrf.h Device interface functions. Copyright Nicola Salmoria and the MAME Team. Visit http://mamedev.org for licensing and usage restrictions. ***************************************************************************/ #pragma once #ifndef __DEVINTRF_H__ #define __DEVINTRF_H__ #include "mamecore.h" #include "romload.h" #include "memory.h" /*************************************************************************** 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_TIMER, /* timer devices */ 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 /* state constants passed to the device_get_info_func */ enum { /* --- the following bits of info are returned as 64-bit signed integers --- */ DEVINFO_INT_FIRST = 0x00000, DEVINFO_INT_TOKEN_BYTES = DEVINFO_INT_FIRST, /* R/O: bytes to allocate for the token */ DEVINFO_INT_INLINE_CONFIG_BYTES, /* R/O: bytes to allocate for the inline configuration */ DEVINFO_INT_CLASS, /* R/O: the device's class */ DEVINFO_INT_ENDIANNESS, /* R/O: either ENDIANNESS_BIG or ENDIANNESS_LITTLE */ DEVINFO_INT_DATABUS_WIDTH, /* R/O: data bus size for each address space (8,16,32,64) */ DEVINFO_INT_DATABUS_WIDTH_0 = DEVINFO_INT_DATABUS_WIDTH + 0, DEVINFO_INT_DATABUS_WIDTH_1 = DEVINFO_INT_DATABUS_WIDTH + 1, DEVINFO_INT_DATABUS_WIDTH_2 = DEVINFO_INT_DATABUS_WIDTH + 2, DEVINFO_INT_DATABUS_WIDTH_3 = DEVINFO_INT_DATABUS_WIDTH + 3, DEVINFO_INT_DATABUS_WIDTH_LAST = DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACES - 1, DEVINFO_INT_ADDRBUS_WIDTH, /* R/O: address bus size for each address space (12-32) */ DEVINFO_INT_ADDRBUS_WIDTH_0 = DEVINFO_INT_ADDRBUS_WIDTH + 0, DEVINFO_INT_ADDRBUS_WIDTH_1 = DEVINFO_INT_ADDRBUS_WIDTH + 1, DEVINFO_INT_ADDRBUS_WIDTH_2 = DEVINFO_INT_ADDRBUS_WIDTH + 2, DEVINFO_INT_ADDRBUS_WIDTH_3 = DEVINFO_INT_ADDRBUS_WIDTH + 3, DEVINFO_INT_ADDRBUS_WIDTH_LAST = DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACES - 1, DEVINFO_INT_ADDRBUS_SHIFT, /* R/O: shift applied to addresses each address space (+3 means >>3, -1 means <<1) */ DEVINFO_INT_ADDRBUS_SHIFT_0 = DEVINFO_INT_ADDRBUS_SHIFT + 0, DEVINFO_INT_ADDRBUS_SHIFT_1 = DEVINFO_INT_ADDRBUS_SHIFT + 1, DEVINFO_INT_ADDRBUS_SHIFT_2 = DEVINFO_INT_ADDRBUS_SHIFT + 2, DEVINFO_INT_ADDRBUS_SHIFT_3 = DEVINFO_INT_ADDRBUS_SHIFT + 3, DEVINFO_INT_ADDRBUS_SHIFT_LAST = DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACES - 1, DEVINFO_INT_CLASS_SPECIFIC = 0x04000, /* R/W: device-specific values start here */ DEVINFO_INT_DEVICE_SPECIFIC = 0x08000, /* R/W: device-specific values start here */ DEVINFO_INT_LAST = 0x0ffff, /* --- the following bits of info are returned as pointers --- */ DEVINFO_PTR_FIRST = 0x10000, DEVINFO_PTR_ROM_REGION = DEVINFO_PTR_FIRST, /* R/O: pointer to device-specific ROM region */ DEVINFO_PTR_MACHINE_CONFIG, /* R/O: pointer to device-specific machine config */ DEVINFO_PTR_CONTRACT_LIST, /* R/O: pointer to list of supported device contracts */ DEVINFO_PTR_INTERNAL_MEMORY_MAP, /* R/O: const addrmap_token *map */ DEVINFO_PTR_INTERNAL_MEMORY_MAP_0 = DEVINFO_PTR_INTERNAL_MEMORY_MAP + 0, DEVINFO_PTR_INTERNAL_MEMORY_MAP_1 = DEVINFO_PTR_INTERNAL_MEMORY_MAP + 1, DEVINFO_PTR_INTERNAL_MEMORY_MAP_2 = DEVINFO_PTR_INTERNAL_MEMORY_MAP + 2, DEVINFO_PTR_INTERNAL_MEMORY_MAP_3 = DEVINFO_PTR_INTERNAL_MEMORY_MAP + 3, DEVINFO_PTR_INTERNAL_MEMORY_MAP_LAST = DEVINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACES - 1, DEVINFO_PTR_DEFAULT_MEMORY_MAP, /* R/O: const addrmap_token *map */ DEVINFO_PTR_DEFAULT_MEMORY_MAP_0 = DEVINFO_PTR_DEFAULT_MEMORY_MAP + 0, DEVINFO_PTR_DEFAULT_MEMORY_MAP_1 = DEVINFO_PTR_DEFAULT_MEMORY_MAP + 1, DEVINFO_PTR_DEFAULT_MEMORY_MAP_2 = DEVINFO_PTR_DEFAULT_MEMORY_MAP + 2, DEVINFO_PTR_DEFAULT_MEMORY_MAP_3 = DEVINFO_PTR_DEFAULT_MEMORY_MAP + 3, DEVINFO_PTR_DEFAULT_MEMORY_MAP_LAST = DEVINFO_PTR_DEFAULT_MEMORY_MAP + ADDRESS_SPACES - 1, DEVINFO_PTR_CLASS_SPECIFIC = 0x14000, /* R/W: device-specific values start here */ DEVINFO_PTR_DEVICE_SPECIFIC = 0x18000, /* R/W: device-specific values start here */ DEVINFO_PTR_LAST = 0x1ffff, /* --- the following bits of info are returned as pointers to functions --- */ DEVINFO_FCT_FIRST = 0x20000, DEVINFO_FCT_START = DEVINFO_FCT_FIRST, /* R/O: device_start_func */ DEVINFO_FCT_STOP, /* R/O: device_stop_func */ DEVINFO_FCT_RESET, /* R/O: device_reset_func */ DEVINFO_FCT_EXECUTE, /* R/O: device_execute_func */ DEVINFO_FCT_VALIDITY_CHECK, /* R/O: device_validity_check_func */ DEVINFO_FCT_NVRAM, /* R/O: device_nvram_func */ DEVINFO_FCT_CUSTOM_CONFIG, /* R/O: device_custom_config_func */ DEVINFO_FCT_CLASS_SPECIFIC = 0x24000, /* R/W: device-specific values start here */ DEVINFO_FCT_DEVICE_SPECIFIC = 0x28000, /* R/W: device-specific values start here */ DEVINFO_FCT_LAST = 0x2ffff, /* --- the following bits of info are returned as NULL-terminated strings --- */ DEVINFO_STR_FIRST = 0x30000, DEVINFO_STR_NAME = DEVINFO_STR_FIRST, /* R/O: name of the device */ DEVINFO_STR_FAMILY, /* R/O: family of the device */ DEVINFO_STR_VERSION, /* R/O: version of the device */ DEVINFO_STR_SOURCE_FILE, /* R/O: file containing the device implementation */ DEVINFO_STR_CREDITS, /* R/O: credits for the device implementation */ DEVINFO_STR_CLASS_SPECIFIC = 0x34000, /* R/W: device-specific values start here */ DEVINFO_STR_DEVICE_SPECIFIC = 0x38000, /* R/W: device-specific values start here */ DEVINFO_STR_LAST = 0x3ffff }; /*************************************************************************** MACROS ***************************************************************************/ #define DEVICE_GET_INFO_NAME(name) device_get_info_##name #define DEVICE_GET_INFO(name) void DEVICE_GET_INFO_NAME(name)(const device_config *device, UINT32 state, deviceinfo *info) #define DEVICE_GET_INFO_CALL(name) DEVICE_GET_INFO_NAME(name)(device, state, info) #define DEVICE_START_NAME(name) device_start_##name #define DEVICE_START(name) void DEVICE_START_NAME(name)(const device_config *device) #define DEVICE_START_CALL(name) DEVICE_START_NAME(name)(device) #define DEVICE_STOP_NAME(name) device_stop_##name #define DEVICE_STOP(name) void DEVICE_STOP_NAME(name)(const device_config *device) #define DEVICE_STOP_CALL(name) DEVICE_STOP_NAME(name)(device) #define DEVICE_RESET_NAME(name) device_reset_##name #define DEVICE_RESET(name) void DEVICE_RESET_NAME(name)(const device_config *device) #define DEVICE_RESET_CALL(name) DEVICE_RESET_NAME(name)(device) #define DEVICE_EXECUTE_NAME(name) device_execute_##name #define DEVICE_EXECUTE(name) INT32 DEVICE_EXECUTE_NAME(name)(const device_config *device, INT32 clocks) #define DEVICE_EXECUTE_CALL(name) DEVICE_EXECUTE_NAME(name)(device, clocks) #define DEVICE_NVRAM_NAME(name) device_nvram_##name #define DEVICE_NVRAM(name) void DEVICE_NVRAM_NAME(name)(const device_config *device, mame_file *file, int read_or_write) #define DEVICE_NVRAM_CALL(name) DEVICE_NVRAM_NAME(name)(device, file, read_or_write) #define DEVICE_VALIDITY_CHECK_NAME(name) device_validity_check_##name #define DEVICE_VALIDITY_CHECK(name) int DEVICE_VALIDITY_CHECK_NAME(name)(const game_driver *driver, const device_config *device) #define DEVICE_VALIDITY_CHECK_CALL(name) DEVICE_VALIDITY_CHECK_NAME(name)(driver, device) #define DEVICE_CUSTOM_CONFIG_NAME(name) device_custom_config_##name #define DEVICE_CUSTOM_CONFIG(name) const union _machine_config_token *DEVICE_CUSTOM_CONFIG_NAME(name)(const device_config *device, UINT32 entrytype, const union _machine_config_token *tokens) #define DEVICE_CUSTOM_CONFIG_CALL(name) DEVICE_CUSTOM_CONFIG_NAME(name)(device, entrytype, tokens) /* device contract lists */ #define DEVICE_CONTRACT_LIST_NAME(name) device_contract_list_##name #define DEVICE_CONTRACT_LIST_START(name) static const device_contract DEVICE_CONTRACT_LIST_NAME(name)[] = { #define DEVICE_CONTRACT_ENTRY(type, var) { type, sizeof(var), &(var) }, #define DEVICE_CONTRACT_LIST_END { NULL, 0, NULL } }; /* macro for specifying a clock derived from an owning device */ #define DERIVED_CLOCK(num, den) (0xff000000 | ((num) << 12) | ((den) << 0)) /* shorthand for accessing devices by machine/type/tag */ #define devtag_get_device(mach,tag) device_list_find_by_tag((mach)->config->devicelist, tag) #define devtag_reset(mach,tag) device_reset(devtag_get_device(mach, tag)) #define devtag_get_address_space(mach,tag,space) #define devtag_get_info_int(mach,tag,state) device_get_info_int(devtag_get_device(mach, tag), state) #define devtag_get_info_ptr(mach,tag,state) device_get_info_ptr(devtag_get_device(mach, tag), state) #define devtag_get_info_fct(mach,tag,state) device_get_info_fct(devtag_get_device(mach, tag), state) #define devtag_get_info_string(mach,tag,state) device_get_info_string(devtag_get_device(mach, tag), state) /* shorthand for getting standard data about device types */ #define devtype_get_endianness(type) devtype_get_info_int(type, DEVINFO_INT_ENDIANNESS) #define devtype_get_databus_width(type,space) devtype_get_info_int(type, DEVINFO_INT_DATABUS_WIDTH + (space)) #define devtype_get_addrbus_width(type,space) devtype_get_info_int(type, DEVINFO_INT_ADDRBUS_WIDTH + (space)) #define devtype_get_addrbus_shift(type,space) devtype_get_info_int(type, DEVINFO_INT_ADDRBUS_SHIFT + (space)) #define devtype_get_name(type) devtype_get_info_string(type, DEVINFO_STR_NAME) #define devtype_get_family(type) devtype_get_info_string(type, DEVINFO_STR_FAMILY) #define devtype_get_version(type) devtype_get_info_string(type, DEVINFO_STR_VERSION) #define devtype_get_source_file(type) devtype_get_info_string(type, DEVINFO_STR_SOURCE_FILE) #define devtype_get_credits(type) devtype_get_info_string(type, DEVINFO_STR_CREDITS) /* shorthand for getting standard data about devices */ #define device_get_endianness(dev) device_get_info_int(dev, DEVINFO_INT_ENDIANNESS) #define device_get_databus_width(dev,space) device_get_info_int(dev, DEVINFO_INT_DATABUS_WIDTH + (space)) #define device_get_addrbus_width(dev,space) device_get_info_int(dev, DEVINFO_INT_ADDRBUS_WIDTH + (space)) #define device_get_addrbus_shift(dev,space) device_get_info_int(dev, DEVINFO_INT_ADDRBUS_SHIFT + (space)) #define device_get_name(dev) device_get_info_string(dev, DEVINFO_STR_NAME) #define device_get_family(dev) device_get_info_string(dev, DEVINFO_STR_FAMILY) #define device_get_version(dev) device_get_info_string(dev, DEVINFO_STR_VERSION) #define device_get_source_file(dev) device_get_info_string(dev, DEVINFO_STR_SOURCE_FILE) #define device_get_credits(dev) device_get_info_string(dev, DEVINFO_STR_CREDITS) /* shorthand for getting standard data about devices by machine/type/tag */ #define devtag_get_endianness(mach,tag) devtag_get_info_int(mach, tag, DEVINFO_INT_ENDIANNESS) #define devtag_get_databus_width(mach,tag,space) devtag_get_info_int(mach, tag, DEVINFO_INT_DATABUS_WIDTH + (space)) #define devtag_get_addrbus_width(mach,tag,space) devtag_get_info_int(mach, tag, DEVINFO_INT_ADDRBUS_WIDTH + (space)) #define devtag_get_addrbus_shift(mach,tag,space) devtag_get_info_int(mach, tag, DEVINFO_INT_ADDRBUS_SHIFT + (space)) #define devtag_get_name(mach,tag) devtag_get_info_string(mach, tag, DEVINFO_STR_NAME) #define devtag_get_family(mach,tag) devtag_get_info_string(mach, tag, DEVINFO_STR_FAMILY) #define devtag_get_version(mach,tag) devtag_get_info_string(mach, tag, DEVINFO_STR_VERSION) #define devtag_get_source_file(mach,tag) devtag_get_info_string(mach, tag, DEVINFO_STR_SOURCE_FILE) #define devtag_get_credits(mach,tag) devtag_get_info_string(mach, tag, DEVINFO_STR_CREDITS) /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ /* forward-declare these types */ typedef union _deviceinfo deviceinfo; /* a device contract */ typedef struct _device_contract device_contract; struct _device_contract { const char * name; /* name of this contract */ UINT32 size; /* size of this contract in bytes */ const void * contract; /* pointer to the contract struct itself */ }; /* device interface function types */ typedef void (*device_get_info_func)(const device_config *device, UINT32 state, deviceinfo *info); typedef void (*device_start_func)(const device_config *device); typedef void (*device_stop_func)(const device_config *device); typedef INT32 (*device_execute_func)(const device_config *device, INT32 clocks); typedef void (*device_reset_func)(const device_config *device); typedef void (*device_nvram_func)(const device_config *device, mame_file *file, int read_or_write); typedef int (*device_validity_check_func)(const game_driver *driver, const device_config *device); typedef const union _machine_config_token *(*device_custom_config_func)(const device_config *device, UINT32 entrytype, const union _machine_config_token *tokens); /* a device_type is simply a pointer to its get_info function */ typedef device_get_info_func device_type; /* the actual deviceinfo union */ union _deviceinfo { INT64 i; /* generic integers */ void * p; /* generic pointers */ genf * f; /* generic function pointers */ char * s; /* generic strings */ device_start_func start; /* DEVINFO_FCT_START */ device_stop_func stop; /* DEVINFO_FCT_STOP */ device_reset_func reset; /* DEVINFO_FCT_RESET */ device_execute_func execute; /* DEVINFO_FCT_EXECUTE */ device_validity_check_func validity_check; /* DEVINFO_FCT_VALIDITY_CHECK */ device_custom_config_func custom_config; /* DEVINFO_FCT_CUSTOM_CONFIG */ device_nvram_func nvram; /* DEVINFO_FCT_NVRAM */ const rom_entry * romregion; /* DEVINFO_PTR_ROM_REGION */ const union _machine_config_token *machine_config; /* DEVINFO_PTR_MACHINE_CONFIG */ const device_contract * contract_list; /* DEVINFO_PTR_CONTRACT_LIST */ const addrmap8_token * internal_map8; /* DEVINFO_PTR_INTERNAL_MEMORY_MAP */ const addrmap16_token * internal_map16; /* DEVINFO_PTR_INTERNAL_MEMORY_MAP */ const addrmap32_token * internal_map32; /* DEVINFO_PTR_INTERNAL_MEMORY_MAP */ const addrmap64_token * internal_map64; /* DEVINFO_PTR_INTERNAL_MEMORY_MAP */ const addrmap8_token * default_map8; /* DEVINFO_PTR_DEFAULT_MEMORY_MAP */ const addrmap16_token * default_map16; /* DEVINFO_PTR_DEFAULT_MEMORY_MAP */ const addrmap32_token * default_map32; /* DEVINFO_PTR_DEFAULT_MEMORY_MAP */ const addrmap64_token * default_map64; /* DEVINFO_PTR_DEFAULT_MEMORY_MAP */ }; /* the configuration for a general device */ struct _device_config { /* device relationships (always valid) */ device_config * next; /* next device (of any type/class) */ device_config * owner; /* device that owns us, or NULL if nobody */ device_config * typenext; /* next device of the same type */ device_config * classnext; /* next device of the same class */ /* device properties (always valid) */ device_type type; /* device type */ device_class devclass; /* device class */ /* device configuration (always valid) */ UINT32 clock; /* device clock */ const addrmap_token * address_map[ADDRESS_SPACES]; /* address maps for each address space */ const void * static_config; /* static device configuration */ void * inline_config; /* inline device configuration */ /* these fields are only valid once the device is attached to a machine */ running_machine * machine; /* machine if device is live */ /* these fields are only valid if the device is live */ UINT8 started; /* TRUE if the start function has succeeded */ void * token; /* token if device is live */ UINT32 tokenbytes; /* size of the token data allocated */ UINT8 * region; /* pointer to region with the device's tag, or NULL */ UINT32 regionbytes; /* size of the region, in bytes */ const address_space * space[ADDRESS_SPACES]; /* auto-discovered address spaces */ device_execute_func execute; /* quick pointer to execute callback */ /* tag (always valid; at end because it is variable-length) */ char tag[1]; /* tag for this instance */ }; /*************************************************************************** FUNCTION PROTOTYPES ***************************************************************************/ /* ----- device configuration ----- */ /* 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); /* remove a device from a device list */ void device_list_remove(device_config **listheadptr, const char *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); /* 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); /* find a given contract on a device */ const device_contract *device_get_contract(const device_config *device, const char *name); /* ----- 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); /* 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); /* 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); /* retrieve a device configuration based on a tag */ const device_config *device_list_find_by_tag(const device_config *listhead, const char *tag); /* 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); /* retrieve a device configuration based on a type and index; DEVICE_TYPE_WILDCARD is allowed */ const device_config *device_list_find_by_index(const device_config *listhead, device_type type, int index); /* ----- class-based device access ----- */ /* return the number of items of a given class */ int device_list_class_items(const device_config *listhead, device_class devclass); /* 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); /* 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); /* 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); /* 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); /* ----- live device management ----- */ /* "attach" a running_machine to its list of devices */ void device_list_attach_machine(running_machine *machine); /* start the configured list of devices for a machine */ void device_list_start(running_machine *machine); /* reset a device based on an allocated device_config */ void device_reset(const device_config *device); /* change the clock on a device */ void device_set_clock(const device_config *device, UINT32 clock); /* allow a device to ask for its initialization to be delayed */ void device_delay_init(const device_config *device); /* ----- device information getters ----- */ /* return an integer state value from an allocated device */ INT64 device_get_info_int(const device_config *device, UINT32 state); /* return a pointer state value from an allocated device */ void *device_get_info_ptr(const device_config *device, UINT32 state); /* return a function pointer state value from an allocated device */ genf *device_get_info_fct(const device_config *device, UINT32 state); /* return a string value from an allocated device */ const char *device_get_info_string(const device_config *device, 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 function pointer from a device type (does not need to be allocated) */ genf *devtype_get_info_fct(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); #endif /* __DEVINTRF_H__ */