/*************************************************************************** devtempl.h Template include for defining devices. Copyright Nicola Salmoria and the MAME Team. Visit http://mamedev.org for licensing and usage restrictions. **************************************************************************** Typical usage is as follows: static const char DEVTEMPLATE_SOURCE[] = __FILE__; // for a primary device.... #define DEVTEMPLATE_ID(p,s) p##devicenameprefix##s #define DEVTEMPLATE_FEATURES DT_HAS_xxx | DT_HAS_yyy | ... #define DEVTEMPLATE_NAME "Device Name String" #include "devtempl.h" // for a derived device.... #define DEVTEMPLATE_DERIVED_ID(p,s) p##derivednameprefix##s #define DEVTEMPLATE_DERIVED_FEATURES DT_HAS_xxx | DT_HAS_yyy | ... #define DEVTEMPLATE_NAME "Derived Name String" #include "devtempl.h" **************************************************************************** Parameters are as follows: DEVTEMPLATE_ID(p,s) - required - macro to produce device function and type names with a prefix of 'p' and a suffix of 's' DEVTEMPLATE_FEATURES - required - bitmask consisting of one of the DT_HAS_* flags, indicating which standard-named callbacks or pointers are specified by this device (everything else is assumed to be NULL, which is the default) DEVTEMPLATE_NAME - required - a string describing the device DEVTEMPLATE_STATE - optional - the name of the device's state structure; by default, this is assumed to be DEVTEMPLATE_ID(,_state) ***************************************************************************/ #define DEVTEMPLATE_ID1(x) DEVTEMPLATE_ID(x,) #define DEVTEMPLATE_DERIVED_ID1(x) DEVTEMPLATE_DERIVED_ID(x,) /* flag bits for DEVTEMPLATE_FEATURES */ #define DT_HAS_START 0x0001 #define DT_HAS_RESET 0x0002 #define DT_HAS_STOP 0x0004 #define DT_HAS_EXECUTE 0x0008 #define DT_HAS_NVRAM 0x0010 #define DT_HAS_CUSTOM_CONFIG 0x0040 #define DT_HAS_ROM_REGION 0x0080 #define DT_HAS_MACHINE_CONFIG 0x0100 #define DT_HAS_INLINE_CONFIG 0x0200 #define DT_HAS_PROGRAM_SPACE 0x1000 #define DT_HAS_DATA_SPACE 0x2000 #define DT_HAS_IO_SPACE 0x4000 /* verify core stuff is specified */ #ifndef DEVTEMPLATE_ID #error DEVTEMPLATE_ID must be specified! #endif #ifndef DEVTEMPLATE_FEATURES #error DEVTEMPLATE_FEATURES must be specified! #endif #if (((DEVTEMPLATE_FEATURES) & DT_HAS_START) == 0) #error Device start routine is required! #endif #ifndef DEVTEMPLATE_NAME #error DEVTEMPLATE_NAME must be specified! #endif #if (((DEVTEMPLATE_FEATURES) & (DT_HAS_PROGRAM_SPACE | DT_HAS_DATA_SPACE | DT_HAS_IO_SPACE)) != 0) #ifndef DEVTEMPLATE_ENDIANNESS #error DEVTEMPLATE_ENDIANNESS must be specified if an address space is present! #endif #endif #ifdef DEVTEMPLATE_DERIVED_FEATURES #ifndef DEVTEMPLATE_DERIVED_NAME #error DEVTEMPLATE_DERIVED_NAME must be specified! #endif #endif /* primary device case */ #ifndef DEVTEMPLATE_DERIVED_FEATURES /* derive standard state name (unless explicitly provided) */ #ifndef DEVTEMPLATE_STATE #define DEVTEMPLATE_STATE DEVTEMPLATE_ID(,_state) #endif /* default to version 1.0 */ #ifndef DEVTEMPLATE_VERSION #define DEVTEMPLATE_VERSION "1.0" #endif /* default to the standard copyright attribution */ #ifndef DEVTEMPLATE_CREDITS #define DEVTEMPLATE_CREDITS "Copyright Nicola Salmoria and the MAME Team" #endif /* declare callback functions */ static DEVICE_START( DEVTEMPLATE_ID(,) ); #if ((DEVTEMPLATE_FEATURES) & DT_HAS_RESET) static DEVICE_RESET( DEVTEMPLATE_ID(,) ); #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_STOP) static DEVICE_STOP( DEVTEMPLATE_ID(,) ); #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_EXECUTE) static DEVICE_EXECUTE( DEVTEMPLATE_ID(,) ); #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_NVRAM) static DEVICE_NVRAM( DEVTEMPLATE_ID(,) ); #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_CUSTOM_CONFIG) static DEVICE_CUSTOM_CONFIG( DEVTEMPLATE_ID(,) ); #endif /* the actual get_info function */ DEVICE_GET_INFO( DEVTEMPLATE_ID(,) ) { switch (state) { /* --- the following bits of info are returned as 64-bit signed integers --- */ case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(DEVTEMPLATE_STATE); break; #if ((DEVTEMPLATE_FEATURES) & DT_HAS_INLINE_CONFIG) case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(DEVTEMPLATE_ID(,_config)); break; #endif #ifdef DEVTEMPLATE_ENDIANNESS case DEVINFO_INT_ENDIANNESS: info->i = DEVTEMPLATE_ENDIANNESS; break; #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_PROGRAM_SPACE) case DEVINFO_INT_DATABUS_WIDTH_0: info->i = DEVTEMPLATE_PGM_DATAWIDTH; break; case DEVINFO_INT_ADDRBUS_WIDTH_0: info->i = DEVTEMPLATE_PGM_ADDRWIDTH; break; #ifdef DEVTEMPLATE_PGM_ADDRSHIFT case DEVINFO_INT_ADDRBUS_SHIFT_0: info->i = DEVTEMPLATE_PGM_ADDRSHIFT; break; #endif #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_DATA_SPACE) case DEVINFO_INT_DATABUS_WIDTH_1: info->i = DEVTEMPLATE_DATA_DATAWIDTH; break; case DEVINFO_INT_ADDRBUS_WIDTH_1: info->i = DEVTEMPLATE_DATA_ADDRWIDTH; break; #ifdef DEVTEMPLATE_DATA_ADDRSHIFT case DEVINFO_INT_ADDRBUS_SHIFT_1: info->i = DEVTEMPLATE_DATA_ADDRSHIFT; break; #endif #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_IO_SPACE) case DEVINFO_INT_DATABUS_WIDTH_2: info->i = DEVTEMPLATE_IO_DATAWIDTH; break; case DEVINFO_INT_ADDRBUS_WIDTH_2: info->i = DEVTEMPLATE_IO_ADDRWIDTH; break; #ifdef DEVTEMPLATE_IO_ADDRSHIFT case DEVINFO_INT_ADDRBUS_SHIFT_2: info->i = DEVTEMPLATE_IO_ADDRSHIFT; break; #endif #endif /* --- the following bits of info are returned as pointers --- */ #if ((DEVTEMPLATE_FEATURES) & DT_HAS_ROM_REGION) case DEVINFO_PTR_ROM_REGION: info->romregion = DEVTEMPLATE_ID1(ROM_NAME()); break; #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_MACHINE_CONFIG) case DEVINFO_PTR_MACHINE_CONFIG: info->machine_config = DEVTEMPLATE_ID1(MACHINE_DRIVER_NAME()); break; #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_PROGRAM_SPACE) #ifdef DEVTEMPLATE_PGM_INTMAP case DEVINFO_PTR_INTERNAL_MEMORY_MAP_0: info->p = (void *)DEVTEMPLATE_PGM_INTMAP; break; #endif #ifdef DEVTEMPLATE_PGM_DEFMAP case DEVINFO_PTR_DEFAULT_MEMORY_MAP_0: info->p = (void *)DEVTEMPLATE_PGM_DEFMAP; break; #endif #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_DATA_SPACE) #ifdef DEVTEMPLATE_DATA_INTMAP case DEVINFO_PTR_INTERNAL_MEMORY_MAP_0: info->p = (void *)DEVTEMPLATE_DATA_INTMAP; break; #endif #ifdef DEVTEMPLATE_DATA_DEFMAP case DEVINFO_PTR_DEFAULT_MEMORY_MAP_0: info->p = (void *)DEVTEMPLATE_DATA_DEFMAP; break; #endif #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_IO_SPACE) #ifdef DEVTEMPLATE_IO_INTMAP case DEVINFO_PTR_INTERNAL_MEMORY_MAP_0: info->p = (void *)DEVTEMPLATE_IO_INTMAP; break; #endif #ifdef DEVTEMPLATE_IO_DEFMAP case DEVINFO_PTR_DEFAULT_MEMORY_MAP_0: info->p = (void *)DEVTEMPLATE_IO_DEFMAP; break; #endif #endif /* --- the following bits of info are returned as pointers to data or functions --- */ #if ((DEVTEMPLATE_FEATURES) & DT_HAS_START) case DEVINFO_FCT_START: info->start = DEVTEMPLATE_ID1(DEVICE_START_NAME()); break; #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_RESET) case DEVINFO_FCT_RESET: info->reset = DEVTEMPLATE_ID1(DEVICE_RESET_NAME()); break; #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_STOP) case DEVINFO_FCT_STOP: info->stop = DEVTEMPLATE_ID1(DEVICE_STOP_NAME()); break; #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_EXECUTE) case DEVINFO_FCT_EXECUTE: info->execute = DEVTEMPLATE_ID1(DEVICE_EXECUTE_NAME()); break; #endif #if ((DEVTEMPLATE_FEATURES) & DT_HAS_NVRAM) case DEVINFO_FCT_NVRAM: info->nvram = DEVTEMPLATE_ID1(DEVICE_NVRAM_NAME()); break; #endif /* --- the following bits of info are returned as NULL-terminated strings --- */ case DEVINFO_STR_NAME: strcpy(info->s, DEVTEMPLATE_NAME); break; } } /* derived device case */ #else /* declare callback functions */ #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_START) static DEVICE_START( DEVTEMPLATE_DERIVED_ID(,) ); #endif #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_RESET) static DEVICE_RESET( DEVTEMPLATE_DERIVED_ID(,) ); #endif #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_STOP) static DEVICE_STOP( DEVTEMPLATE_DERIVED_ID(,) ); #endif #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_EXECUTE) static DEVICE_EXECUTE( DEVTEMPLATE_DERIVED_ID(,) ); #endif #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_NVRAM) static DEVICE_NVRAM( DEVTEMPLATE_DERIVED_ID(,) ); #endif #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_CUSTOM_CONFIG) static DEVICE_CUSTOM_CONFIG( DEVTEMPLATE_DERIVED_ID(,) ); #endif /* the actual get_info function */ DEVICE_GET_INFO( DEVTEMPLATE_DERIVED_ID(,) ) { switch (state) { /* --- the following bits of info are returned as 64-bit signed integers --- */ #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_PROGRAM_SPACE) case DEVINFO_INT_DATABUS_WIDTH_0: info->i = DEVTEMPLATE_DERIVED_PGM_DATAWIDTH; break; case DEVINFO_INT_ADDRBUS_WIDTH_0: info->i = DEVTEMPLATE_DERIVED_PGM_ADDRWIDTH; break; #ifdef DEVTEMPLATE_PGM_ADDRSHIFT case DEVINFO_INT_ADDRBUS_SHIFT_0: info->i = DEVTEMPLATE_DERIVED_PGM_ADDRSHIFT; break; #endif #endif #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_DATA_SPACE) case DEVINFO_INT_DATABUS_WIDTH_1: info->i = DEVTEMPLATE_DERIVED_DATA_DATAWIDTH; break; case DEVINFO_INT_ADDRBUS_WIDTH_1: info->i = DEVTEMPLATE_DERIVED_DATA_ADDRWIDTH; break; #ifdef DEVTEMPLATE_DATA_ADDRSHIFT case DEVINFO_INT_ADDRBUS_SHIFT_1: info->i = DEVTEMPLATE_DERIVED_DATA_ADDRSHIFT; break; #endif #endif #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_IO_SPACE) case DEVINFO_INT_DATABUS_WIDTH_2: info->i = DEVTEMPLATE_DERIVED_IO_DATAWIDTH; break; case DEVINFO_INT_ADDRBUS_WIDTH_2: info->i = DEVTEMPLATE_DERIVED_IO_ADDRWIDTH; break; #ifdef DEVTEMPLATE_IO_ADDRSHIFT case DEVINFO_INT_ADDRBUS_SHIFT_2: info->i = DEVTEMPLATE_DERIVED_IO_ADDRSHIFT; break; #endif #endif /* --- the following bits of info are returned as pointers --- */ #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_ROM_REGION) case DEVINFO_PTR_ROM_REGION: info->romregion = DEVTEMPLATE_DERIVED_ID1(ROM_NAME()); break; #endif #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_MACHINE_CONFIG) case DEVINFO_PTR_MACHINE_CONFIG: info->machine_config = DEVTEMPLATE_DERIVED_ID1(MACHINE_DRIVER_NAME()); break; #endif /* --- the following bits of info are returned as pointers to data or functions --- */ #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_START) case DEVINFO_FCT_START: info->start = DEVTEMPLATE_DERIVED_ID1(DEVICE_START_NAME()); break; #endif #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_RESET) case DEVINFO_FCT_RESET: info->reset = DEVTEMPLATE_DERIVED_ID1(DEVICE_RESET_NAME()); break; #endif #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_STOP) case DEVINFO_FCT_STOP: info->stop = DEVTEMPLATE_DERIVED_ID1(DEVICE_STORE_NAME()); break; #endif #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_EXECUTE) case DEVINFO_FCT_EXECUTE: info->execute = DEVTEMPLATE_DERIVED_ID1(DEVICE_EXECUTE_NAME()); break; #endif #if ((DEVTEMPLATE_DERIVED_FEATURES) & DT_HAS_NVRAM) case DEVINFO_FCT_NVRAM: info->nvram = DEVTEMPLATE_DERIVED_ID1(DEVICE_NVRAM_NAME()); break; #endif /* --- the following bits of info are returned as NULL-terminated strings --- */ case DEVINFO_STR_NAME: strcpy(info->s, DEVTEMPLATE_DERIVED_NAME); break; default: DEVICE_GET_INFO_CALL(DEVTEMPLATE_ID(,)); break; } } #endif #undef DT_HAS_RESET #undef DT_HAS_STOP #undef DT_HAS_EXECUTE #undef DT_HAS_NVRAM #undef DT_HAS_CUSTOM_CONFIG #undef DT_HAS_ROM_REGION #undef DT_HAS_MACHINE_CONFIG #undef DT_HAS_INLINE_CONFIG #undef DT_HAS_PROGRAM_SPACE #undef DT_HAS_DATA_SPACE #undef DT_HAS_IO_SPACE #undef DEVTEMPLATE_DERIVED_ID #undef DEVTEMPLATE_DERIVED_FEATURES #undef DEVTEMPLATE_DERIVED_NAME