diff options
Diffstat (limited to 'src/emu/devintrf.h')
-rw-r--r-- | src/emu/devintrf.h | 785 |
1 files changed, 399 insertions, 386 deletions
diff --git a/src/emu/devintrf.h b/src/emu/devintrf.h index d824c1b1626..fa41f383c54 100644 --- a/src/emu/devintrf.h +++ b/src/emu/devintrf.h @@ -4,8 +4,36 @@ Device interface functions. - Copyright Nicola Salmoria and the MAME Team. - Visit http://mamedev.org for licensing and usage restrictions. +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ @@ -20,231 +48,111 @@ -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -// forward references -struct rom_entry; -union machine_config_token; - - -// 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) -}; - - -// state constants passed to the device_get_config_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_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_GET_RUNTIME_INFO, // R/O: device_get_runtime_info_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 -***************************************************************************/ +//************************************************************************** +// MACROS +//************************************************************************** -#define DEVICE_GET_INFO_NAME(name) device_get_config_##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_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 machine_config_token *DEVICE_CUSTOM_CONFIG_NAME(name)(const device_config *device, UINT32 entrytype, const machine_config_token *tokens) -#define DEVICE_CUSTOM_CONFIG_CALL(name) DEVICE_CUSTOM_CONFIG_NAME(name)(device, entrytype, tokens) +// 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) (mach)->device(tag) +#define devtag_reset(mach,tag) (mach)->device(tag)->reset() -#define DEVICE_GET_RUNTIME_INFO_NAME(name) device_get_runtime_info_##name -#define DEVICE_GET_RUNTIME_INFO(name) void DEVICE_GET_RUNTIME_INFO_NAME(name)(running_device *device, UINT32 state, deviceinfo *info) -#define DEVICE_GET_RUNTIME_INFO_CALL(name) DEVICE_GET_RUNTIME_INFO_NAME(name)(device, state, info) -#define DEVICE_START_NAME(name) device_start_##name -#define DEVICE_START(name) void DEVICE_START_NAME(name)(running_device *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)(running_device *device) -#define DEVICE_STOP_CALL(name) DEVICE_STOP_NAME(name)(device) +//************************************************************************** +// DEVICE CONFIGURATION MACROS +//************************************************************************** -#define DEVICE_RESET_NAME(name) device_reset_##name -#define DEVICE_RESET(name) void DEVICE_RESET_NAME(name)(running_device *device) -#define DEVICE_RESET_CALL(name) DEVICE_RESET_NAME(name)(device) +// configure devices +#define MDRV_DEVICE_CONFIG(_config) \ + TOKEN_UINT32_PACK1(MCONFIG_TOKEN_DEVICE_CONFIG, 8), \ + TOKEN_PTR(voidptr, &(_config)), -#define DEVICE_EXECUTE_NAME(name) device_execute_##name -#define DEVICE_EXECUTE(name) INT32 DEVICE_EXECUTE_NAME(name)(running_device *device, INT32 clocks) -#define DEVICE_EXECUTE_CALL(name) DEVICE_EXECUTE_NAME(name)(device, clocks) +#define MDRV_DEVICE_CONFIG_CLEAR() \ + TOKEN_UINT32_PACK1(MCONFIG_TOKEN_DEVICE_CONFIG, 8), \ + TOKEN_PTR(voidptr, NULL), -#define DEVICE_NVRAM_NAME(name) device_nvram_##name -#define DEVICE_NVRAM(name) void DEVICE_NVRAM_NAME(name)(running_device *device, mame_file *file, int read_or_write) -#define DEVICE_NVRAM_CALL(name) DEVICE_NVRAM_NAME(name)(device, file, read_or_write) +#define MDRV_DEVICE_CLOCK(_clock) \ + TOKEN_UINT64_PACK2(MCONFIG_TOKEN_DEVICE_CLOCK, 8, _clock, 32), +#define MDRV_DEVICE_INLINE_DATA16(_index, _data) \ + TOKEN_UINT32_PACK3(MCONFIG_TOKEN_DEVICE_INLINE_DATA16, 8, _index, 8, (UINT16)(_data), 16), \ -// macro for specifying a clock derived from an owning device -#define DERIVED_CLOCK(num, den) (0xff000000 | ((num) << 12) | ((den) << 0)) +#define MDRV_DEVICE_INLINE_DATA32(_index, _data) \ + TOKEN_UINT32_PACK2(MCONFIG_TOKEN_DEVICE_INLINE_DATA32, 8, _index, 8), \ + TOKEN_UINT32((UINT32)(_data)), +#define MDRV_DEVICE_INLINE_DATA64(_index, _data) \ + TOKEN_UINT32_PACK2(MCONFIG_TOKEN_DEVICE_INLINE_DATA64, 8, _index, 8), \ + TOKEN_UINT64((UINT64)(_data)), -// shorthand for accessing devices by machine/type/tag -#define devtag_get_device(mach,tag) (mach)->device(tag) +#ifdef PTR64 +#define MDRV_DEVICE_INLINE_DATAPTR(_index, _data) MDRV_DEVICE_INLINE_DATA64(_index, (FPTR)(_data)) +#else +#define MDRV_DEVICE_INLINE_DATAPTR(_index, _data) MDRV_DEVICE_INLINE_DATA32(_index, (FPTR)(_data)) +#endif -#define devtag_reset(mach,tag) (mach)->device(tag)->reset() +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -// forward-declare these types +// forward references class region_info; class device_config; -class running_device; -union deviceinfo; +class device_config_interface; +class device_t; +class device_interface; +struct rom_entry; +union machine_config_token; +class machine_config; -// exception types +// exception classes class device_missing_dependencies : public emu_exception { }; -// device interface function types -typedef void (*device_get_config_func)(const device_config *device, UINT32 state, deviceinfo *info); -typedef int (*device_validity_check_func)(const game_driver *driver, const device_config *device); -typedef const machine_config_token *(*device_custom_config_func)(const device_config *device, UINT32 entrytype, const machine_config_token *tokens); +// a device_type is simply a pointer to its alloc function +typedef device_config *(*device_type)(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); -typedef void (*device_start_func)(running_device *device); -typedef void (*device_stop_func)(running_device *device); -typedef INT32 (*device_execute_func)(running_device *device, INT32 clocks); -typedef void (*device_reset_func)(running_device *device); -typedef void (*device_nvram_func)(running_device *device, mame_file *file, int read_or_write); -typedef void (*device_get_runtime_info_func)(running_device *device, UINT32 state, deviceinfo *info); -// a device_type is simply a pointer to its get_info function -typedef device_get_config_func device_type; +// ======================> tagged_device_list - -// tagged_device_list is a tagged_list with additional searching based on type or class -template<class T> class tagged_device_list : public tagged_list<T> +// tagged_device_list is a tagged_list with additional searching based on type +template<class T> +class tagged_device_list : public tagged_list<T> { typedef tagged_list<T> super; - + public: + tagged_device_list(resource_pool &pool = global_resource_pool) + : tagged_list<T>(pool) { } + // pull the generic forms forward using super::first; using super::count; using super::index; using super::find; - + // provide type-specific overrides T *first(device_type type) const { T *cur; - for (cur = super::first(); cur != NULL && cur->type != type; cur = cur->next) ; + for (cur = super::first(); cur != NULL && cur->type() != type; cur = cur->next()) ; return cur; } - + int count(device_type type) const { int num = 0; for (const T *curdev = first(type); curdev != NULL; curdev = curdev->typenext()) num++; return num; } - + int index(device_type type, T *object) const { int num = 0; @@ -252,13 +160,13 @@ public: if (cur == object) return num; return -1; } - + int index(device_type type, const char *tag) const { T *object = find(tag); - return (object != NULL && object->type == type) ? index(type, object) : -1; + return (object != NULL && object->type() == type) ? index(type, object) : -1; } - + T *find(device_type type, int index) const { for (T *cur = first(type); cur != NULL; cur = cur->typenext()) @@ -266,294 +174,399 @@ public: return NULL; } - // provide class-specific overrides - T *first(device_class devclass) const + // provide interface-specific overrides + template<class I> + bool first(I *&intf) const { - T *cur; - for (cur = super::first(); cur != NULL && cur->devclass != devclass; cur = cur->next) ; - return cur; - } - - int count(device_class devclass) const - { - int num = 0; - for (const T *curdev = first(devclass); curdev != NULL; curdev = curdev->classnext()) num++; - return num; - } - - int index(device_class devclass, T *object) const - { - int num = 0; - for (T *cur = first(devclass); cur != NULL; cur = cur->classnext(), num++) - if (cur == object) return num; - return -1; + for (T *cur = super::first(); cur != NULL; cur = cur->next()) + if (cur->interface(intf)) + return true; + return false; } +}; - int index(device_class devclass, const char *tag) const - { - T *object = find(tag); - return (object != NULL && object->devclass == devclass) ? index(devclass, object) : -1; - } - T *find(device_class devclass, int index) const - { - for (T *cur = first(devclass); cur != NULL; cur = cur->classnext()) - if (index-- == 0) return cur; - return NULL; - } -}; +// ======================> device_config_list // device_config_list manages a list of device_configs typedef tagged_device_list<device_config> device_config_list; -// device_list manages a list of running_devices -class device_list : public tagged_device_list<running_device> -{ - running_machine *machine; - static void static_reset(running_machine *machine); - static void static_stop(running_machine *machine); +// ======================> device_list +// device_list manages a list of device_ts +class device_list : public tagged_device_list<device_t> +{ + running_machine *m_machine; + + static void static_reset(running_machine *machine); + static void static_exit(running_machine *machine); + static void static_pre_save(running_machine *machine, void *param); + static void static_post_load(running_machine *machine, void *param); + public: - device_list(); + device_list(resource_pool &pool = global_resource_pool); void import_config_list(const device_config_list &list, running_machine &machine); void start_all(); + void debug_setup_all(); void reset_all(); - void stop_all(); }; -// 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 - device_get_runtime_info_func get_runtime_info; // DEVINFO_FCT_GET_RUNTIME_INFO - const rom_entry * romregion; // DEVINFO_PTR_ROM_REGION - const machine_config_token *machine_config; // DEVINFO_PTR_MACHINE_CONFIG - 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 -enum device_space -{ - AS_PROGRAM = 0, - AS_DATA = 1, - AS_IO = 2 -}; - +// ======================> device_config // device_config represents a device configuration that is attached to a machine_config class device_config { DISABLE_COPYING(device_config); - -public: - device_config(const device_config *owner, device_type type, const char *tag, UINT32 clock); + + friend class device_t; + friend class device_config_interface; + template<class T> friend class tagged_list; + +protected: + // construction/destruction + device_config(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock); virtual ~device_config(); - device_config *typenext() const +public: + // iteration helpers + device_config *next() const { return m_next; } + device_config *typenext() const; + device_config *owner() const { return m_owner; } + + // interface helpers + template<class T> bool interface(const T *&intf) const { intf = dynamic_cast<const T *>(this); return (intf != NULL); } + template<class T> bool next(T *&intf) const { - device_config *cur; - for (cur = this->next; cur != NULL && cur->type != type; cur = cur->next) ; - return cur; + for (device_config *cur = m_next; cur != NULL; cur = cur->m_next) + if (cur->interface(intf)) + return true; + return false; } - device_config *classnext() const - { - device_config *cur; - for (cur = this->next; cur != NULL && cur->devclass != devclass; cur = cur->next) ; - return cur; - } + // owned object helpers + astring &subtag(astring &dest, const char *tag) const; + astring &siblingtag(astring &dest, const char *tag) const; - // get state from a device config - virtual endianness_t endianness() const { return static_cast<endianness_t>(get_config_int(DEVINFO_INT_ENDIANNESS)); } - virtual UINT8 databus_width(int spacenum = 0) const { return get_config_int(DEVINFO_INT_DATABUS_WIDTH + spacenum); } - virtual UINT8 addrbus_width(int spacenum = 0) const { return get_config_int(DEVINFO_INT_ADDRBUS_WIDTH + spacenum); } - virtual INT8 addrbus_shift(int spacenum = 0) const { return get_config_int(DEVINFO_INT_ADDRBUS_SHIFT + spacenum); } - - virtual const rom_entry *rom_region() const { return reinterpret_cast<const rom_entry *>(get_config_ptr(DEVINFO_PTR_ROM_REGION)); } - virtual const machine_config_token *machine_config_tokens() const { return reinterpret_cast<const machine_config_token *>(get_config_ptr(DEVINFO_PTR_MACHINE_CONFIG)); } - virtual const addrmap_token *internal_map(int spacenum = 0) const { return reinterpret_cast<const addrmap_token *>(get_config_ptr(DEVINFO_PTR_INTERNAL_MEMORY_MAP + spacenum)); } - virtual const addrmap_token *default_map(int spacenum = 0) const { return reinterpret_cast<const addrmap_token *>(get_config_ptr(DEVINFO_PTR_DEFAULT_MEMORY_MAP + spacenum)); } - - virtual const char *name() const { return get_config_string(DEVINFO_STR_NAME); } - virtual const char *family() const { return get_config_string(DEVINFO_STR_FAMILY); } - virtual const char *version() const { return get_config_string(DEVINFO_STR_VERSION); } - virtual const char *source_file() const { return get_config_string(DEVINFO_STR_SOURCE_FILE); } - virtual const char *credits() const { return get_config_string(DEVINFO_STR_CREDITS); } + // basic information getters + device_type type() const { return m_type; } + UINT32 clock() const { return m_clock; } const char *tag() const { return m_tag; } + const void *static_config() const { return m_static_config; } - INT64 get_config_int(UINT32 state) const; - void *get_config_ptr(UINT32 state) const; - genf *get_config_fct(UINT32 state) const; - const char *get_config_string(UINT32 state) const; + // methods that wrap both interface-level and device-level behavior + void process_token(UINT32 entrytype, const machine_config_token *&tokens); + void config_complete(); + bool validity_check(const game_driver &driver) const; + + //------------------- begin derived class overrides - astring &subtag(astring &dest, const char *tag) const; - astring &siblingtag(astring &dest, const char *tag) const; + // required operation overrides + virtual device_t *alloc_device(running_machine &machine) const = 0; + // optional operation overrides +protected: + virtual bool device_process_token(UINT32 entrytype, const machine_config_token *&tokens); + virtual void device_config_complete(); + virtual bool device_validity_check(const game_driver &driver) const; + + // required information overrides +public: + virtual const char *name() const = 0; + + // optional information overrides + virtual const rom_entry *rom_region() const; + virtual const machine_config_token *machine_config_tokens() const; + + //------------------- end derived class overrides + +protected: // device relationships - device_config * next; // next device (of any type/class) - device_config * owner; // device that owns us, or NULL if nobody + device_config * m_next; // next device (of any type/class) + device_config * m_owner; // device that owns us, or NULL if nobody + device_config_interface *m_interface_list; // head of interface list - // device properties - device_type type; // device type - device_class devclass; // device class + const device_type m_type; // device type + UINT32 m_clock; // device clock - // device configuration - 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 + const machine_config & m_machine_config; // reference to the machine's configuration + const void * m_static_config; // static device configuration + UINT64 m_inline_data[16]; // array of inline configuration values private: astring m_tag; // tag for this instance }; -// running_device represents a device that is live and attached to a running_machine -class running_device -{ - DISABLE_COPYING(running_device); - const device_config & m_baseconfig; +// ======================> device_config_interface + +// device_config_interface represents configuration information for a particular device interface +class device_config_interface +{ + DISABLE_COPYING(device_config_interface); -public: // private eventually - const address_space * addrspace[ADDRESS_SPACES]; // auto-discovered address spaces +protected: + // construction/destruction + device_config_interface(const machine_config &mconfig, device_config &devconfig); + virtual ~device_config_interface(); public: - running_device(running_machine &machine, const device_config &config); - virtual ~running_device(); + // casting helpers + const device_config &devconfig() const { return m_device_config; } + operator const device_config &() const { return m_device_config; } + operator const device_config *() const { return &m_device_config; } + + // iteration helpers + device_config_interface *interface_next() const { return m_interface_next; } + template<class T> bool next(T *&intf) const { return m_device_config.next(intf); } + + // optional operation overrides + virtual void interface_config_complete(); + virtual bool interface_process_token(UINT32 entrytype, const machine_config_token *&tokens); + virtual bool interface_validity_check(const game_driver &driver) const; + +protected: + const device_config & m_device_config; + const machine_config & m_machine_config; + device_config_interface * m_interface_next; +}; - const device_config &baseconfig() const { return m_baseconfig; } - inline const address_space *space(int index = 0) const; - inline const address_space *space(device_space index) const; - astring &subtag(astring &dest, const char *tag) const { return m_baseconfig.subtag(dest, tag); } - astring &siblingtag(astring &dest, const char *tag) const { return m_baseconfig.siblingtag(dest, tag); } +// ======================> device_t - const region_info *subregion(const char *tag) const; - running_device *subdevice(const char *tag) const; +// device_t represents a device that is live and attached to a running_machine +class device_t +{ + DISABLE_COPYING(device_t); - running_device *typenext() const - { - running_device *cur; - for (cur = this->next; cur != NULL && cur->type != type; cur = cur->next) ; - return cur; - } + friend class device_interface; + template<class T> friend class tagged_list; + friend class device_list; - running_device *classnext() const +protected: + // construction/destruction + device_t(running_machine &machine, const device_config &config); + virtual ~device_t(); + +public: + // iteration helpers + device_t *next() const { return m_next; } + device_t *typenext() const; + device_t *owner() const { return m_owner; } + + // interface helpers + template<class T> bool interface(T *&intf) { intf = dynamic_cast<T *>(this); return (intf != NULL); } + template<class T> bool next(T *&intf) const { - running_device *cur; - for (cur = this->next; cur != NULL && cur->devclass != devclass; cur = cur->next) ; - return cur; + for (device_t *cur = m_next; cur != NULL; cur = cur->m_next) + if (cur->interface(intf)) + return true; + return false; } - void start(); + // owned object helpers + astring &subtag(astring &dest, const char *tag) const { return m_baseconfig.subtag(dest, tag); } + astring &siblingtag(astring &dest, const char *tag) const { return m_baseconfig.siblingtag(dest, tag); } + const region_info *subregion(const char *tag) const; + device_t *subdevice(const char *tag) const; + device_t *siblingdevice(const char *tag) const; + + // configuration helpers + const device_config &baseconfig() const { return m_baseconfig; } + const region_info *region() const { return m_region; } + + // state helpers + bool started() const { return m_started; } void reset(); - void stop(); - void set_clock(UINT32 clock); - // get state from a device config - endianness_t endianness() const { return m_baseconfig.endianness(); } - UINT8 databus_width(int spacenum = 0) const { return m_baseconfig.databus_width(spacenum); } - UINT8 addrbus_width(int spacenum = 0) const { return m_baseconfig.addrbus_width(spacenum); } - INT8 addrbus_shift(int spacenum = 0) const { return m_baseconfig.addrbus_shift(spacenum); } + // clock/timing accessors + UINT32 clock() const { return m_clock; } + UINT32 unscaled_clock() const { return m_unscaled_clock; } + void set_unscaled_clock(UINT32 clock); + double clock_scale() const { return m_clock_scale; } + void set_clock_scale(double clockscale); + attotime clocks_to_attotime(UINT64 clocks) const; + UINT64 attotime_to_clocks(attotime duration) const; + + // basic information getters ... pass through to underlying config + device_type type() const { return m_baseconfig.type(); } + const char *name() const { return m_baseconfig.name(); } + const char *tag() const { return m_baseconfig.tag(); } + // machine and ROM configuration getters ... pass through to underlying config const rom_entry *rom_region() const { return m_baseconfig.rom_region(); } const machine_config_token *machine_config_tokens() const { return m_baseconfig.machine_config_tokens(); } - const addrmap_token *internal_map(int spacenum = 0) const { return m_baseconfig.internal_map(spacenum); } - const addrmap_token *default_map(int spacenum = 0) const { return m_baseconfig.default_map(spacenum); } - const char *name() const { return m_baseconfig.name(); } - const char *family() const { return m_baseconfig.family(); } - const char *version() const { return m_baseconfig.version(); } - const char *source_file() const { return m_baseconfig.source_file(); } - const char *credits() const { return m_baseconfig.credits(); } - const char *tag() const { return m_tag; } +public: + running_machine * machine; - INT64 get_config_int(UINT32 state) const { return m_baseconfig.get_config_int(state); } - void *get_config_ptr(UINT32 state) const { return m_baseconfig.get_config_ptr(state); } - genf *get_config_fct(UINT32 state) const { return m_baseconfig.get_config_fct(state); } - const char *get_config_string(UINT32 state) const { return m_baseconfig.get_config_string(state); } +protected: + // miscellaneous helpers + void start(); + void debug_setup(); + void pre_save(); + void post_load(); + void notify_clock_changed(); + + //------------------- begin derived class overrides + + // device-level overrides + virtual void device_start() = 0; + virtual void device_reset(); + virtual void device_pre_save(); + virtual void device_post_load(); + virtual void device_clock_changed(); + virtual void device_debug_setup(); + + //------------------- end derived class overrides + + running_machine & m_machine; + + // device relationships + device_t * m_next; // next device (of any type/class) + device_t * m_owner; // device that owns us, or NULL if nobody + device_interface * m_interface_list; // head of interface list + + bool m_started; // true if the start function has succeeded + UINT32 m_clock; // device clock + const region_info * m_region; // our device-local region + + const device_config & m_baseconfig; // reference to our device_config + UINT32 m_unscaled_clock; // unscaled clock + double m_clock_scale; // clock scale factor + attoseconds_t m_attoseconds_per_clock;// period in attoseconds +}; - INT64 get_runtime_int(UINT32 state); - void *get_runtime_ptr(UINT32 state); - const char *get_runtime_string(UINT32 state); - void set_address_space(int spacenum, const address_space *space); +// running_device is an alias for device_t for now +typedef device_t running_device; - // these fields are only valid once the device is attached to a machine - running_machine * machine; // machine if device is live - // device relationships - running_device * next; // next device (of any type/class) - running_device * owner; // device that owns us, or NULL if nobody - // device properties - device_type type; // device type - device_class devclass; // device class +// ======================> device_interface - // device configuration - UINT32 clock; // device clock +// device_interface represents runtime information for a particular device interface +class device_interface +{ + DISABLE_COPYING(device_interface); - // these fields are only valid if the device is live - bool started; // true if the start function has succeeded - void * token; // token if device is live - UINT32 tokenbytes; // size of the token data allocated - const region_info * region; // our device-local region +protected: + // construction/destruction + device_interface(running_machine &machine, const device_config &config, device_t &device); + virtual ~device_interface(); + +public: + // casting helpers + device_t &device() { return m_device; } + operator device_t &() { return m_device; } + operator device_t *() { return &m_device; } + + // iteration helpers + device_interface *interface_next() const { return m_interface_next; } + template<class T> bool next(T *&intf) const { return m_device.next(intf); } + + // optional operation overrides + virtual void interface_pre_start(); + virtual void interface_post_start(); + virtual void interface_pre_reset(); + virtual void interface_post_reset(); + virtual void interface_pre_save(); + virtual void interface_post_load(); + virtual void interface_clock_changed(); + virtual void interface_debug_setup(); + +protected: + device_interface * m_interface_next; + device_t & m_device; +}; - device_execute_func execute; // quick pointer to execute callback - device_get_runtime_info_func get_runtime_info; -private: - astring m_tag; -}; +//************************************************************************** +// INLINE FUNCTIONS +//************************************************************************** -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ +// ======================> device config helpers + +// find the next device_config of the same type +inline device_config *device_config::typenext() const +{ + device_config *cur; + for (cur = m_next; cur != NULL && cur->m_type != m_type; cur = cur->m_next) ; + return cur; +} + +// create a tag for an object that is owned by this device +inline astring &device_config::subtag(astring &dest, const char *_tag) const +{ + return (this != NULL) ? dest.cpy(m_tag).cat(":").cat(_tag) : dest.cpy(_tag); +} + +// create a tag for an object that a sibling to this device +inline astring &device_config::siblingtag(astring &dest, const char *_tag) const +{ + return (this != NULL && m_owner != NULL) ? m_owner->subtag(dest, _tag) : dest.cpy(_tag); +} -/*------------------------------------------------- - space - return an address space within a - device --------------------------------------------------*/ -inline const address_space *running_device::space(int index) const + +// ======================> running device helpers + +// find the next device_t of the same type +inline device_t *device_t::typenext() const +{ + device_t *cur; + for (cur = m_next; cur != NULL && cur->type() != type(); cur = cur->m_next) ; + return cur; +} + + + +// ======================> device clock management + +// returns the current device's unscaled running clock speed +inline int device_get_clock(device_t *device) { - return addrspace[index]; + return device->unscaled_clock(); } -inline const address_space *running_device::space(device_space index) const +// sets the current device's clock speed and then adjusts for scaling +inline void device_set_clock(device_t *device, int clock) { - return space(static_cast<int>(index)); + device->set_unscaled_clock(clock); } +// returns the current scaling factor for a device's clock speed +inline double device_get_clock_scale(device_t *device) +{ + return device->clock_scale(); +} + +// sets the current scaling factor for a device's clock speed +inline void device_set_clock_scale(device_t *device, double clockscale) +{ + device->set_clock_scale(clockscale); +} + +// converts a number of clock ticks to an attotime +inline attotime device_clocks_to_attotime(device_t *device, UINT64 clocks) +{ + return device->clocks_to_attotime(clocks); +} + +// converts a duration as attotime to device clock ticks +inline UINT64 device_attotime_to_clocks(device_t *device, attotime duration) +{ + return device->attotime_to_clocks(duration); +} #endif /* __DEVINTRF_H__ */ |