diff options
author | 2010-06-08 06:09:57 +0000 | |
---|---|---|
committer | 2010-06-08 06:09:57 +0000 | |
commit | 100564d41225bfd2fa163c0174557ed979285b4e (patch) | |
tree | 0be83fbde1ddb95633293c9faee60d0f2bc6ace1 /src/emu/devlegcy.h | |
parent | 962dca9f57d61cdea65ee32c6362bf3d0d1e2dae (diff) |
WARNING: There are likely to be regressions in both functionality and
performance as a result of this change. Do not panic; report issues to the
list in the short term and I will look into them. There are probably also
some details I forgot to mention. Please ask questions if anything is not
clear.
NOTE: This is a major internal change to the way devices are handled in
MAME. There is a small impact on drivers, but the bulk of the changes are
to the devices themselves. Full documentation on the new device handling
is in progress at http://mamedev.org/devwiki/index.php/MAME_Device_Basics
Defined two new casting helpers: [Aaron Giles]
downcast<type>(value) should be used for safe and efficient downcasting
from a base class to a derived class. It wraps static_cast<> by adding
an assert that a matching dynamic_cast<> returns the same result in
debug builds.
crosscast<type>(value) should be used for safe casting from one type to
another in multiple inheritance scenarios. It compiles to a
dynamic_cast<> plus an assert on the result. Since it does not optimize
down to static_cast<>, you should prefer downcast<> over crosscast<>
when you can.
Redefined running_device to be a proper C++ class (now called device_t).
Same for device_config (still called device_config). All devices and
device_configs must now be derived from these base classes. This means
each device type now has a pair of its own unique classes that describe
the device. Drivers are encouraged to use the specific device types
instead of the generic running_device or device_t classes. Drivers that
have a state class defined in their header file are encouraged to use
initializers off the constructor to locate devices. [Aaron Giles]
Removed the following fields from the device and device configuration
classes as they never were necessary or provided any use: device class,
device family, source file, version, credits. [Aaron Giles]
Added templatized variant of machine->device() which performs a downcast
as part of the device fetch. Thus machine->device<timer_device>("timer")
will locate a device named "timer", downcast it to a timer_device, and
assert if the downcast fails. [Aaron Giles]
Removed most publically accessible members of running_device/device_t in
favor of inline accessor functions. The only remaining public member is
machine. Thus all references to device->type are now device->type(), etc.
[Aaron Giles]
Created a number of device interface classes which are designed to be mix-
ins for the device classes, providing specific extended functionality and
information. There are standard interface classes for sound, execution,
state, nvram, memory, and disassembly. Devices can opt into 0 or more of
these classes. [Aaron Giles]
Converted the classic CPU device to a standard device that uses the
execution, state, memory, and disassembly interfaces. Used this new class
(cpu_device) to implement the existing CPU device interface. In the future
it will be possible to convert each CPU core to its own device type, but
for now they are still all CPU devices with a cpu_type() that specifies
exactly which kind of CPU. [Aaron Giles]
Created a new header devlegcy.h which wraps the old device interface using
some special template classes. To use these with an existing device,
simply remove from the device header the DEVICE_GET_INFO() declaration and
the #define mapping the ALL_CAPS name to the DEVICE_GET_INFO. In their
place #include "devlegcy.h" and use the DECLARE_LEGACY_DEVICE() macro.
In addition, there is a DECLARE_LEGACY_SOUND_DEVICE() macro for wrapping
existing sound devices into new-style devices, and a
DECLARE_LEGACY_NVRAM_DEVICE() for wrapping NVRAM devices. Also moved the
token and inline_config members to the legacy device class, as these are
not used in modern devices. [Aaron Giles]
Converted the standard base devices (VIDEO_SCREEN, SPEAKER, and TIMER)
from legacy devices to the new C++ style. Also renamed VIDEO_SCREEN to
simply SCREEN. The various global functions that were previously used to
access information or modify the state of these devices are now replaced
by methods on the device classes. Specifically:
video_screen_configure() == screen->configure()
video_screen_set_visarea() == screen->set_visible_area()
video_screen_update_partial() == screen->update_partial()
video_screen_update_now() == screen->update_now()
video_screen_get_vpos() == screen->vpos()
video_screen_get_hpos() == screen->hpos()
video_screen_get_vblank() == screen->vblank()
video_screen_get_hblank() == screen->hblank()
video_screen_get_width() == screen->width()
video_screen_get_height() == screen->height()
video_screen_get_visible_area() == screen->visible_area()
video_screen_get_time_until_pos() == screen->time_until_pos()
video_screen_get_time_until_vblank_start() ==
screen->time_until_vblank_start()
video_screen_get_time_until_vblank_end() ==
screen->time_until_vblank_end()
video_screen_get_time_until_update() == screen->time_until_update()
video_screen_get_scan_period() == screen->scan_period()
video_screen_get_frame_period() == screen->frame_period()
video_screen_get_frame_number() == screen->frame_number()
timer_device_adjust_oneshot() == timer->adjust()
timer_device_adjust_periodic() == timer->adjust()
timer_device_reset() == timer->reset()
timer_device_enable() == timer->enable()
timer_device_enabled() == timer->enabled()
timer_device_get_param() == timer->param()
timer_device_set_param() == timer->set_param()
timer_device_get_ptr() == timer->get_ptr()
timer_device_set_ptr() == timer->set_ptr()
timer_device_timeelapsed() == timer->time_elapsed()
timer_device_timeleft() == timer->time_left()
timer_device_starttime() == timer->start_time()
timer_device_firetime() == timer->fire_time()
Updated all drivers that use the above functions to fetch the specific
device type (timer_device or screen_device) and call the appropriate
method. [Aaron Giles]
Changed machine->primary_screen and the 'screen' parameter to VIDEO_UPDATE
to specifically pass in a screen_device object. [Aaron Giles]
Defined a new custom interface for the Z80 daisy chain. This interface
behaves like the standard interfaces, and can be added to any device that
implements the Z80 daisy chain behavior. Converted all existing Z80 daisy
chain devices to new-style devices that inherit this interface.
[Aaron Giles]
Changed the way CPU state tables are built up. Previously, these were data
structures defined by a CPU core which described all the registers and how
to output them. This functionality is now part of the state interface and
is implemented via the device_state_entry class. Updated all CPU cores
which were using the old data structure to use the new form. The syntax is
currently awkward, but will be cleaner for CPUs that are native new
devices. [Aaron Giles]
Converted the okim6295 and eeprom devices to the new model. These were
necessary because they both require multiple interfaces to operate and it
didn't make sense to create legacy device templates for these single cases.
(okim6295 needs the sound interface and the memory interface, while eeprom
requires both the nvram and memory interfaces). [Aaron Giles]
Changed parameters in a few callback functions from pointers to references
in situations where they are guaranteed to never be NULL. [Aaron Giles]
Removed MDRV_CPU_FLAGS() which was only used for disabling a CPU. Changed
it to MDRV_DEVICE_DISABLE() instead. Updated drivers. [Aaron Giles]
Reorganized the token parsing for machine configurations. The core parsing
code knows how to create/replace/remove devices, but all device token
parsing is now handled in the device_config class, which in turn will make
use of any interface classes or device-specific token handling for custom
token processing. [Aaron Giles]
Moved many validity checks out of validity.c and into the device interface
classes. For example, address space validation is now part of the memory
interface class. [Aaron Giles]
Consolidated address space parameters (bus width, endianness, etc.) into
a single address_space_config class. Updated all code that queried for
address space parameters to use the new mechanism. [Aaron Giles]
Diffstat (limited to 'src/emu/devlegcy.h')
-rw-r--r-- | src/emu/devlegcy.h | 583 |
1 files changed, 583 insertions, 0 deletions
diff --git a/src/emu/devlegcy.h b/src/emu/devlegcy.h new file mode 100644 index 00000000000..2632dccbfd7 --- /dev/null +++ b/src/emu/devlegcy.h @@ -0,0 +1,583 @@ +/*************************************************************************** + + devlegcy.h + + Legacy device helpers. + +**************************************************************************** + + 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. + +***************************************************************************/ + +#pragma once + +#ifndef __DEVLEGCY_H__ +#define __DEVLEGCY_H__ + + + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +// 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_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_NVRAM, // R/O: device_nvram_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_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_START_NAME(name) device_start_##name +#define DEVICE_START(name) void DEVICE_START_NAME(name)(device_t *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)(device_t *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)(device_t *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)(device_t *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)(device_t *device, mame_file *file, int read_or_write) +#define DEVICE_NVRAM_CALL(name) DEVICE_NVRAM_NAME(name)(device, file, read_or_write) + + +// defined types and such for a standard legacy device +#define DECLARE_LEGACY_DEVICE(name, basename) \ + DEVICE_GET_INFO( basename ); \ + typedef legacy_device< \ + DEVICE_GET_INFO_NAME(basename), \ + legacy_device_base \ + > basename##_device; \ + typedef legacy_device_config< \ + DEVICE_GET_INFO_NAME(basename), \ + legacy_device_config_base, \ + basename##_device \ + > basename##_device_config; \ + const device_type name = basename##_device_config::static_alloc_device_config + + +// defined types and such for a sound legacy device +#define DECLARE_LEGACY_SOUND_DEVICE(name, basename) \ + DEVICE_GET_INFO( basename ); \ + typedef legacy_device< \ + DEVICE_GET_INFO_NAME(basename), \ + legacy_sound_device_base \ + > basename##_sound_device; \ + typedef legacy_device_config< \ + DEVICE_GET_INFO_NAME(basename), \ + legacy_sound_device_config_base, \ + basename##_sound_device \ + > basename##_sound_device_config; \ + const device_type SOUND_##name = basename##_sound_device_config::static_alloc_device_config + + +// defined types and such for a memory legacy device +#define DECLARE_LEGACY_MEMORY_DEVICE(name, basename) \ + DEVICE_GET_INFO( basename ); \ + typedef legacy_device< \ + DEVICE_GET_INFO_NAME(basename), \ + legacy_memory_device_base \ + > basename##_device; \ + typedef legacy_device_config< \ + DEVICE_GET_INFO_NAME(basename), \ + legacy_memory_device_config_base, \ + basename##_device \ + > basename##_device_config; \ + const device_type name = basename##_device_config::static_alloc_device_config + + +// defined types and such for a memory legacy device +#define DECLARE_LEGACY_NVRAM_DEVICE(name, basename) \ + DEVICE_GET_INFO( basename ); \ + typedef legacy_device< \ + DEVICE_GET_INFO_NAME(basename), \ + legacy_nvram_device_base \ + > basename##_device; \ + typedef legacy_device_config< \ + DEVICE_GET_INFO_NAME(basename), \ + legacy_nvram_device_config_base, \ + basename##_device \ + > basename##_device_config; \ + const device_type name = basename##_device_config::static_alloc_device_config + + + +//************************************************************************** +// DEVICE_CONFIGURATION_MACROS +//************************************************************************** + +// inline device configurations that require 32 bits of storage in the token +#define MDRV_DEVICE_CONFIG_DATA32_EXPLICIT(_size, _offset, _val) \ + TOKEN_UINT32_PACK3(MCONFIG_TOKEN_DEVICE_CONFIG_DATA32, 8, _size, 4, _offset, 12), \ + TOKEN_UINT32((UINT32)(_val)), + +#define MDRV_DEVICE_CONFIG_DATA32(_struct, _field, _val) \ + MDRV_DEVICE_CONFIG_DATA32_EXPLICIT(structsizeof(_struct, _field), offsetof(_struct, _field), _val) + +#define MDRV_DEVICE_CONFIG_DATA32_ARRAY(_struct, _field, _index, _val) \ + MDRV_DEVICE_CONFIG_DATA32_EXPLICIT(structsizeof(_struct, _field[0]), offsetof(_struct, _field) + (_index) * structsizeof(_struct, _field[0]), _val) + +#define MDRV_DEVICE_CONFIG_DATA32_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val) \ + MDRV_DEVICE_CONFIG_DATA32_EXPLICIT(structsizeof(_memstruct, _member), offsetof(_struct, _field) + (_index) * structsizeof(_struct, _field[0]) + offsetof(_memstruct, _member), _val) + +#define MDRV_NEW_DEVICE_CONFIG_DATA32(_struct, _field, _val) \ + MDRV_DEVICE_CONFIG_DATA32_EXPLICIT(DEVCONFIG_SIZEOF(_struct, _field), DEVCONFIG_OFFSETOF(_struct, _field), _val) + +#define MDRV_NEW_DEVICE_CONFIG_DATA32_ARRAY(_struct, _field, _index, _val) \ + MDRV_DEVICE_CONFIG_DATA32_EXPLICIT(DEVCONFIG_SIZEOF(_struct, _field[0]), DEVCONFIG_OFFSETOF(_struct, _field) + (_index) * DEVCONFIG_SIZEOF(_struct, _field[0]), _val) + +#define MDRV_NEW_DEVICE_CONFIG_DATA32_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val) \ + MDRV_DEVICE_CONFIG_DATA32_EXPLICIT(DEVCONFIG_SIZEOF(_memstruct, _member), DEVCONFIG_OFFSETOF(_struct, _field) + (_index) * DEVCONFIG_SIZEOF(_struct, _field[0]) + DEVCONFIG_OFFSETOF(_memstruct, _member), _val) + + +// inline device configurations that require 32 bits of fixed-point storage in the token +#define MDRV_DEVICE_CONFIG_DATAFP32_EXPLICIT(_size, _offset, _val, _fixbits) \ + TOKEN_UINT32_PACK4(MCONFIG_TOKEN_DEVICE_CONFIG_DATAFP32, 8, _size, 4, _fixbits, 6, _offset, 12), \ + TOKEN_UINT32((INT32)((float)(_val) * (float)(1 << (_fixbits)))), + +#define MDRV_DEVICE_CONFIG_DATAFP32(_struct, _field, _val, _fixbits) \ + MDRV_DEVICE_CONFIG_DATAFP32_EXPLICIT(structsizeof(_struct, _field), offsetof(_struct, _field), _val, _fixbits) + +#define MDRV_DEVICE_CONFIG_DATAFP32_ARRAY(_struct, _field, _index, _val, _fixbits) \ + MDRV_DEVICE_CONFIG_DATAFP32_EXPLICIT(structsizeof(_struct, _field[0]), offsetof(_struct, _field) + (_index) * structsizeof(_struct, _field[0]), _val, _fixbits) + +#define MDRV_DEVICE_CONFIG_DATAFP32_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val, _fixbits) \ + MDRV_DEVICE_CONFIG_DATAFP32_EXPLICIT(structsizeof(_memstruct, _member), offsetof(_struct, _field) + (_index) * structsizeof(_struct, _field[0]) + offsetof(_memstruct, _member), _val, _fixbits) + +#define MDRV_DEVICE_NEW_CONFIG_DATAFP32(_struct, _field, _val, _fixbits) \ + MDRV_DEVICE_CONFIG_DATAFP32_EXPLICIT(DEVCONFIG_SIZEOF(_struct, _field), DEVCONFIG_OFFSETOF(_struct, _field), _val, _fixbits) + +#define MDRV_DEVICE_NEW_CONFIG_DATAFP32_ARRAY(_struct, _field, _index, _val, _fixbits) \ + MDRV_DEVICE_CONFIG_DATAFP32_EXPLICIT(DEVCONFIG_SIZEOF(_struct, _field[0]), DEVCONFIG_OFFSETOF(_struct, _field) + (_index) * DEVCONFIG_SIZEOF(_struct, _field[0]), _val, _fixbits) + +#define MDRV_DEVICE_NEW_CONFIG_DATAFP32_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val, _fixbits) \ + MDRV_DEVICE_CONFIG_DATAFP32_EXPLICIT(DEVCONFIG_SIZEOF(_memstruct, _member), DEVCONFIG_OFFSETOF(_struct, _field) + (_index) * DEVCONFIG_SIZEOF(_struct, _field[0]) + DEVCONFIG_OFFSETOF(_memstruct, _member), _val, _fixbits) + + +// inline device configurations that require 64 bits of storage in the token +#define MDRV_DEVICE_CONFIG_DATA64_EXPLICIT(_size, _offset, _val) \ + TOKEN_UINT32_PACK3(MCONFIG_TOKEN_DEVICE_CONFIG_DATA64, 8, _size, 4, _offset, 12), \ + TOKEN_UINT64((UINT64)(_val)), + +#define MDRV_DEVICE_CONFIG_DATA64(_struct, _field, _val) \ + MDRV_DEVICE_CONFIG_DATA64_EXPLICIT(structsizeof(_struct, _field), offsetof(_struct, _field), _val) + +#define MDRV_DEVICE_CONFIG_DATA64_ARRAY(_struct, _field, _index, _val) \ + MDRV_DEVICE_CONFIG_DATA64_EXPLICIT(structsizeof(_struct, _field[0]), offsetof(_struct, _field) + (_index) * structsizeof(_struct, _field[0]), _val) + +#define MDRV_DEVICE_CONFIG_DATA64_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val) \ + MDRV_DEVICE_CONFIG_DATA64_EXPLICIT(structsizeof(_memstruct, _member), offsetof(_struct, _field) + (_index) * structsizeof(_struct, _field[0]) + offsetof(_memstruct, _member), _val) + +#define MDRV_DEVICE_NEW_CONFIG_DATA64(_struct, _field, _val) \ + MDRV_DEVICE_CONFIG_DATA64_EXPLICIT(DEVCONFIG_SIZEOF(_struct, _field), DEVCONFIG_OFFSETOF(_struct, _field), _val) + +#define MDRV_DEVICE_NEW_CONFIG_DATA64_ARRAY(_struct, _field, _index, _val) \ + MDRV_DEVICE_CONFIG_DATA64_EXPLICIT(DEVCONFIG_SIZEOF(_struct, _field[0]), DEVCONFIG_OFFSETOF(_struct, _field) + (_index) * DEVCONFIG_SIZEOF(_struct, _field[0]), _val) + +#define MDRV_DEVICE_NEW_CONFIG_DATA64_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val) \ + MDRV_DEVICE_CONFIG_DATA64_EXPLICIT(DEVCONFIG_SIZEOF(_memstruct, _member), DEVCONFIG_OFFSETOF(_struct, _field) + (_index) * DEVCONFIG_SIZEOF(_struct, _field[0]) + DEVCONFIG_OFFSETOF(_memstruct, _member), _val) + + +// inline device configurations that require a pointer-sized amount of storage in the token +#ifdef PTR64 +#define MDRV_DEVICE_CONFIG_DATAPTR_EXPLICIT(_struct, _size, _offset) MDRV_DEVICE_CONFIG_DATA64_EXPLICIT(_struct, _size, _offset) +#define MDRV_DEVICE_CONFIG_DATAPTR(_struct, _field, _val) MDRV_DEVICE_CONFIG_DATA64(_struct, _field, _val) +#define MDRV_DEVICE_CONFIG_DATAPTR_ARRAY(_struct, _field, _index, _val) MDRV_DEVICE_CONFIG_DATA64_ARRAY(_struct, _field, _index, _val) +#define MDRV_DEVICE_CONFIG_DATAPTR_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val) MDRV_DEVICE_CONFIG_DATA64_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val) +#define MDRV_DEVICE_NEW_CONFIG_DATAPTR(_struct, _field, _val) MDRV_DEVICE_NEW_CONFIG_DATA64(_struct, _field, _val) +#define MDRV_DEVICE_NEW_CONFIG_DATAPTR_ARRAY(_struct, _field, _index, _val) MDRV_DEVICE_NEW_CONFIG_DATA64_ARRAY(_struct, _field, _index, _val) +#define MDRV_DEVICE_NEW_CONFIG_DATAPTR_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val) MDRV_DEVICE_NEW_CONFIG_DATA64_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val) +#else +#define MDRV_DEVICE_CONFIG_DATAPTR_EXPLICIT(_struct, _size, _offset) MDRV_DEVICE_CONFIG_DATA32_EXPLICIT(_struct, _size, _offset) +#define MDRV_DEVICE_CONFIG_DATAPTR(_struct, _field, _val) MDRV_DEVICE_CONFIG_DATA32(_struct, _field, _val) +#define MDRV_DEVICE_CONFIG_DATAPTR_ARRAY(_struct, _field, _index, _val) MDRV_DEVICE_CONFIG_DATA32_ARRAY(_struct, _field, _index, _val) +#define MDRV_DEVICE_CONFIG_DATAPTR_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val) MDRV_DEVICE_CONFIG_DATA32_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val) +#define MDRV_DEVICE_CONFIG_NEW_DATAPTR(_struct, _field, _val) MDRV_DEVICE_NEW_CONFIG_DATA32(_struct, _field, _val) +#define MDRV_DEVICE_CONFIG_NEW_DATAPTR_ARRAY(_struct, _field, _index, _val) MDRV_DEVICE_NEW_CONFIG_DATA32_ARRAY(_struct, _field, _index, _val) +#define MDRV_DEVICE_CONFIG_NEW_DATAPTR_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val) MDRV_DEVICE_NEW_CONFIG_DATA32_ARRAY_MEMBER(_struct, _field, _index, _memstruct, _member, _val) +#endif + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +union deviceinfo; + +char *get_temp_string_buffer(void); +resource_pool &machine_get_pool(running_machine &machine); + + +// device interface function types +typedef void (*device_get_config_func)(const device_config *device, UINT32 state, deviceinfo *info); + +typedef void (*device_start_func)(device_t *device); +typedef void (*device_stop_func)(device_t *device); +typedef INT32 (*device_execute_func)(device_t *device, INT32 clocks); +typedef void (*device_reset_func)(device_t *device); +typedef void (*device_nvram_func)(device_t *device, mame_file *file, int read_or_write); + + +// 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_nvram_func nvram; // DEVINFO_FCT_NVRAM + 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 +}; + + +// ======================> legacy_device_config_base + +// legacy_device_config_base describes a base configuration class for legacy devices +class legacy_device_config_base : public device_config +{ + friend class legacy_device_base; + friend class legacy_nvram_device_base; + +protected: + // construction/destruction + legacy_device_config_base(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock, device_get_config_func get_config); + virtual ~legacy_device_config_base(); + + // allocators - defined in derived classes + + // basic information getters +public: + virtual const char *name() const { return get_legacy_config_string(DEVINFO_STR_NAME); } + virtual const rom_entry *rom_region() const { return reinterpret_cast<const rom_entry *>(get_legacy_config_ptr(DEVINFO_PTR_ROM_REGION)); } + virtual const machine_config_token *machine_config_tokens() const { return reinterpret_cast<const machine_config_token *>(get_legacy_config_ptr(DEVINFO_PTR_MACHINE_CONFIG)); } + + // access to legacy inline configuartion + void *inline_config() const { return m_inline_config; } + +protected: + // access to legacy configuration info + INT64 get_legacy_config_int(UINT32 state) const; + void *get_legacy_config_ptr(UINT32 state) const; + genf *get_legacy_config_fct(UINT32 state) const; + const char *get_legacy_config_string(UINT32 state) const; + + // internal state + device_get_config_func m_get_config_func; + void * m_inline_config; +}; + + + +// ======================> legacy_device_base + +// legacy_device_base serves as a common base class for legacy devices +class legacy_device_base : public device_t +{ +protected: + // construction/destruction + legacy_device_base(running_machine &_machine, const device_config &config); + virtual ~legacy_device_base(); + +public: + // access to legacy token + void *token() const { return m_token; } + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // internal state + const legacy_device_config_base & m_config; + void * m_token; +}; + + + +// ======================> legacy_sound_device_config_base + +// legacy_sound_device_config is a device_config with a sound interface +class legacy_sound_device_config_base : public legacy_device_config_base, + public device_config_sound_interface +{ +protected: + // construction/destruction + legacy_sound_device_config_base(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock, device_get_config_func get_config); +}; + + + +// ======================> legacy_sound_device_base + +// legacy_sound_device is a legacy_device_base with a sound interface +class legacy_sound_device_base : public legacy_device_base, + public device_sound_interface +{ +protected: + // construction/destruction + legacy_sound_device_base(running_machine &machine, const device_config &config); +}; + + + +// ======================> legacy_memory_device_config_base + +// legacy_memory_device_config is a device_config with a memory interface +class legacy_memory_device_config_base : public legacy_device_config_base, + public device_config_memory_interface +{ +protected: + // construction/destruction + legacy_memory_device_config_base(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock, device_get_config_func get_config); + + // device_config overrides + virtual void device_config_complete(); + + // device_config_memory_interface overrides + virtual const address_space_config *memory_space_config(int spacenum = 0) const { return (spacenum == 0) ? &m_space_config : NULL; } + + // internal state + address_space_config m_space_config; +}; + + + +// ======================> legacy_memory_device_base + +// legacy_memory_device is a legacy_device_base with a memory interface +class legacy_memory_device_base : public legacy_device_base, + public device_memory_interface +{ +protected: + // construction/destruction + legacy_memory_device_base(running_machine &machine, const device_config &config); +}; + + + +// ======================> legacy_nvram_device_config + +// legacy_nvram_device_config is a device_config with a nvram interface +class legacy_nvram_device_config_base : public legacy_device_config_base, + public device_config_nvram_interface +{ +protected: + // construction/destruction + legacy_nvram_device_config_base(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock, device_get_config_func get_config); +}; + + + +// ======================> legacy_nvram_device + +// legacy_nvram_device is a legacy_device_base with a nvram interface +class legacy_nvram_device_base : public legacy_device_base, + public device_nvram_interface +{ +protected: + // construction/destruction + legacy_nvram_device_base(running_machine &machine, const device_config &config); + + // device_nvram_interface overrides + virtual void nvram_default(); + virtual void nvram_read(mame_file &file); + virtual void nvram_write(mame_file &file); +}; + + +// ======================> legacy_device_config + +// legacy_device_config template describes a new device_config derivative that implements +// the old device callbacks +template< + device_get_config_func _get_config, + class _config_base, + class _running_class +> +class legacy_device_config : public _config_base +{ + // construction/destruction + legacy_device_config(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock) + : _config_base(mconfig, type, tag, owner, clock, _get_config) + { + } + +public: + // allocators + static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) + { + return global_alloc(legacy_device_config(mconfig, static_alloc_device_config, tag, owner, clock)); + } + + virtual device_t *alloc_device(running_machine &machine) const + { + return pool_alloc(machine_get_pool(machine), _running_class(machine, *this)); +// return auto_alloc(&machine, device_t(machine, *this)); + } +}; + + + +// ======================> legacy_device + +// legacy_device template describes a new device_t derivative that implements +// the old device callbacks +template< + device_get_config_func _get_config, + class _device_base +> +class legacy_device : public _device_base +{ + template< + device_get_config_func __get_config, + class __config_base, + class __running_class + > + friend class legacy_device_config; + + legacy_device(running_machine &_machine, const legacy_device_config_base &config) + : _device_base(_machine, config) + { + } +}; + + + +#endif /* __DEVLEGCY_H__ */ |