summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/driver.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/driver.h')
-rw-r--r--trunk/src/emu/driver.h545
1 files changed, 545 insertions, 0 deletions
diff --git a/trunk/src/emu/driver.h b/trunk/src/emu/driver.h
new file mode 100644
index 00000000000..8789fd727d1
--- /dev/null
+++ b/trunk/src/emu/driver.h
@@ -0,0 +1,545 @@
+/***************************************************************************
+
+ driver.h
+
+ Core driver device base class.
+
+****************************************************************************
+
+ 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 __EMU_H__
+#error Dont include this file directly; include emu.h instead.
+#endif
+
+#ifndef __DRIVER_H__
+#define __DRIVER_H__
+
+
+//**************************************************************************
+// CONFIGURATION MACROS
+//**************************************************************************
+
+// core machine callbacks
+#define MCFG_MACHINE_START(_func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_MACHINE_START, MACHINE_START_NAME(_func)); \
+
+#define MCFG_MACHINE_START_OVERRIDE(_class, _func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_MACHINE_START, driver_callback_delegate(&_class::_func, #_class "::" #_func, downcast<_class *>(&config.root_device())));
+
+#define MCFG_MACHINE_RESET(_func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_MACHINE_RESET, MACHINE_RESET_NAME(_func)); \
+
+#define MCFG_MACHINE_RESET_OVERRIDE(_class, _func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_MACHINE_RESET, driver_callback_delegate(&_class::_func, #_class "::" #_func, downcast<_class *>(&config.root_device())));
+
+
+// core sound callbacks
+#define MCFG_SOUND_START(_func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_SOUND_START, SOUND_START_NAME(_func)); \
+
+#define MCFG_SOUND_START_OVERRIDE(_class, _func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_SOUND_START, driver_callback_delegate(&_class::_func, #_class "::" #_func, downcast<_class *>(&config.root_device())));
+
+#define MCFG_SOUND_RESET(_func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_SOUND_RESET, SOUND_RESET_NAME(_func)); \
+
+#define MCFG_SOUND_RESET_OVERRIDE(_class, _func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_SOUND_RESET, driver_callback_delegate(&_class::_func, #_class "::" #_func, downcast<_class *>(&config.root_device())));
+
+
+// core video callbacks
+#define MCFG_PALETTE_INIT(_func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_PALETTE_INIT, PALETTE_INIT_NAME(_func)); \
+
+#define MCFG_PALETTE_INIT_OVERRIDE(_class, _func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_PALETTE_INIT, driver_callback_delegate(&_class::_func, #_class "::" #_func, downcast<_class *>(&config.root_device())));
+
+#define MCFG_VIDEO_START(_func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_VIDEO_START, VIDEO_START_NAME(_func)); \
+
+#define MCFG_VIDEO_START_OVERRIDE(_class, _func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_VIDEO_START, driver_callback_delegate(&_class::_func, #_class "::" #_func, downcast<_class *>(&config.root_device())));
+
+#define MCFG_VIDEO_RESET(_func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_VIDEO_RESET, VIDEO_RESET_NAME(_func)); \
+
+#define MCFG_VIDEO_RESET_OVERRIDE(_class, _func) \
+ driver_device::static_set_callback(*owner, driver_device::CB_VIDEO_RESET, driver_callback_delegate(&_class::_func, #_class "::" #_func, downcast<_class *>(&config.root_device())));
+
+
+
+//**************************************************************************
+// OTHER MACROS
+//**************************************************************************
+
+// macros to wrap legacy callbacks
+#define MACHINE_START_NAME(name) machine_start_##name
+#define MACHINE_START(name) void MACHINE_START_NAME(name)(running_machine &machine)
+#define MACHINE_START_CALL(name) MACHINE_START_NAME(name)(machine)
+
+#define MACHINE_RESET_NAME(name) machine_reset_##name
+#define MACHINE_RESET(name) void MACHINE_RESET_NAME(name)(running_machine &machine)
+#define MACHINE_RESET_CALL(name) MACHINE_RESET_NAME(name)(machine)
+
+#define SOUND_START_NAME(name) sound_start_##name
+#define SOUND_START(name) void SOUND_START_NAME(name)(running_machine &machine)
+#define SOUND_START_CALL(name) SOUND_START_NAME(name)(machine)
+
+#define SOUND_RESET_NAME(name) sound_reset_##name
+#define SOUND_RESET(name) void SOUND_RESET_NAME(name)(running_machine &machine)
+#define SOUND_RESET_CALL(name) SOUND_RESET_NAME(name)(machine)
+
+#define PALETTE_INIT_NAME(name) palette_init_##name
+#define PALETTE_INIT(name) void PALETTE_INIT_NAME(name)(running_machine &machine)
+#define PALETTE_INIT_CALL(name) PALETTE_INIT_NAME(name)(machine)
+
+#define VIDEO_START_NAME(name) video_start_##name
+#define VIDEO_START(name) void VIDEO_START_NAME(name)(running_machine &machine)
+#define VIDEO_START_CALL(name) VIDEO_START_NAME(name)(machine)
+
+#define VIDEO_RESET_NAME(name) video_reset_##name
+#define VIDEO_RESET(name) void VIDEO_RESET_NAME(name)(running_machine &machine)
+#define VIDEO_RESET_CALL(name) VIDEO_RESET_NAME(name)(machine)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+typedef delegate<void ()> driver_callback_delegate;
+
+// legacy callback functions
+typedef void (*legacy_callback_func)(running_machine &machine);
+
+
+// ======================> driver_device
+
+// base class for machine driver-specific devices
+class driver_device : public device_t
+{
+public:
+ // construction/destruction
+ driver_device(const machine_config &mconfig, device_type type, const char *tag);
+ virtual ~driver_device();
+
+ // getters
+ const game_driver &system() const { assert(m_system != NULL); return *m_system; }
+
+ // indexes into our generic callbacks
+ enum callback_type
+ {
+ CB_MACHINE_START,
+ CB_MACHINE_RESET,
+ CB_SOUND_START,
+ CB_SOUND_RESET,
+ CB_PALETTE_INIT,
+ CB_VIDEO_START,
+ CB_VIDEO_RESET,
+ CB_COUNT
+ };
+
+ // inline configuration helpers
+ static void static_set_game(device_t &device, const game_driver &game);
+ static void static_set_callback(device_t &device, callback_type type, legacy_callback_func callback);
+ static void static_set_callback(device_t &device, callback_type type, driver_callback_delegate callback);
+
+ // generic helpers
+ template<class _DriverClass, void (_DriverClass::*_Function)()>
+ static void static_wrapper(driver_device &device)
+ {
+ (downcast<_DriverClass &>(device).*_Function)();
+ }
+
+ // generic interrupt generators
+ void generic_pulse_irq_line(device_execute_interface &exec, int irqline, int cycles);
+ void generic_pulse_irq_line_and_vector(device_execute_interface &exec, int irqline, int vector, int cycles);
+
+ INTERRUPT_GEN_MEMBER( nmi_line_pulse );
+ INTERRUPT_GEN_MEMBER( nmi_line_assert );
+
+ INTERRUPT_GEN_MEMBER( irq0_line_hold );
+ INTERRUPT_GEN_MEMBER( irq0_line_pulse );
+ INTERRUPT_GEN_MEMBER( irq0_line_assert );
+
+ INTERRUPT_GEN_MEMBER( irq1_line_hold );
+ INTERRUPT_GEN_MEMBER( irq1_line_pulse );
+ INTERRUPT_GEN_MEMBER( irq1_line_assert );
+
+ INTERRUPT_GEN_MEMBER( irq2_line_hold );
+ INTERRUPT_GEN_MEMBER( irq2_line_pulse );
+ INTERRUPT_GEN_MEMBER( irq2_line_assert );
+
+ INTERRUPT_GEN_MEMBER( irq3_line_hold );
+ INTERRUPT_GEN_MEMBER( irq3_line_pulse );
+ INTERRUPT_GEN_MEMBER( irq3_line_assert );
+
+ INTERRUPT_GEN_MEMBER( irq4_line_hold );
+ INTERRUPT_GEN_MEMBER( irq4_line_pulse );
+ INTERRUPT_GEN_MEMBER( irq4_line_assert );
+
+ INTERRUPT_GEN_MEMBER( irq5_line_hold );
+ INTERRUPT_GEN_MEMBER( irq5_line_pulse );
+ INTERRUPT_GEN_MEMBER( irq5_line_assert );
+
+ INTERRUPT_GEN_MEMBER( irq6_line_hold );
+ INTERRUPT_GEN_MEMBER( irq6_line_pulse );
+ INTERRUPT_GEN_MEMBER( irq6_line_assert );
+
+ INTERRUPT_GEN_MEMBER( irq7_line_hold );
+ INTERRUPT_GEN_MEMBER( irq7_line_pulse );
+ INTERRUPT_GEN_MEMBER( irq7_line_assert );
+
+ // watchdog read/write handlers
+ DECLARE_WRITE8_MEMBER( watchdog_reset_w );
+ DECLARE_READ8_MEMBER( watchdog_reset_r );
+ DECLARE_WRITE16_MEMBER( watchdog_reset16_w );
+ DECLARE_READ16_MEMBER( watchdog_reset16_r );
+ DECLARE_WRITE32_MEMBER( watchdog_reset32_w );
+ DECLARE_READ32_MEMBER( watchdog_reset32_r );
+
+ // generic audio
+ void soundlatch_setclearedvalue(UINT16 value) { m_latch_clear_value = value; }
+
+ // sound latch readers
+ DECLARE_READ8_MEMBER( soundlatch_byte_r );
+ DECLARE_READ8_MEMBER( soundlatch2_byte_r );
+ DECLARE_READ8_MEMBER( soundlatch3_byte_r );
+ DECLARE_READ8_MEMBER( soundlatch4_byte_r );
+ DECLARE_READ16_MEMBER( soundlatch_word_r );
+ DECLARE_READ16_MEMBER( soundlatch2_word_r );
+ DECLARE_READ16_MEMBER( soundlatch3_word_r );
+ DECLARE_READ16_MEMBER( soundlatch4_word_r );
+
+ // sound latch writers
+ DECLARE_WRITE8_MEMBER( soundlatch_byte_w );
+ DECLARE_WRITE8_MEMBER( soundlatch2_byte_w );
+ DECLARE_WRITE8_MEMBER( soundlatch3_byte_w );
+ DECLARE_WRITE8_MEMBER( soundlatch4_byte_w );
+ DECLARE_WRITE16_MEMBER( soundlatch_word_w );
+ DECLARE_WRITE16_MEMBER( soundlatch2_word_w );
+ DECLARE_WRITE16_MEMBER( soundlatch3_word_w );
+ DECLARE_WRITE16_MEMBER( soundlatch4_word_w );
+
+ // sound latch clearers
+ DECLARE_WRITE8_MEMBER( soundlatch_clear_byte_w );
+ DECLARE_WRITE8_MEMBER( soundlatch2_clear_byte_w );
+ DECLARE_WRITE8_MEMBER( soundlatch3_clear_byte_w );
+ DECLARE_WRITE8_MEMBER( soundlatch4_clear_byte_w );
+
+ // generic video
+ void flip_screen_set(UINT32 on);
+ void flip_screen_set_no_update(UINT32 on);
+ void flip_screen_x_set(UINT32 on);
+ void flip_screen_y_set(UINT32 on);
+ UINT32 flip_screen() const { return m_flip_screen_x; }
+ UINT32 flip_screen_x() const { return m_flip_screen_x; }
+ UINT32 flip_screen_y() const { return m_flip_screen_y; }
+
+ // templatized palette writers for 8-bit palette data
+ template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift> DECLARE_WRITE8_MEMBER( palette_8bit_byte_w );
+
+ // templatized palette writers for 16-bit palette data
+ template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift> DECLARE_WRITE8_MEMBER( palette_16bit_byte_le_w );
+ template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift> DECLARE_WRITE8_MEMBER( palette_16bit_byte_be_w );
+ template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift> DECLARE_WRITE8_MEMBER( palette_16bit_byte_split_lo_w );
+ template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift> DECLARE_WRITE8_MEMBER( palette_16bit_byte_split_hi_w );
+ template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift> DECLARE_WRITE16_MEMBER( palette_16bit_word_w );
+ template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift> DECLARE_WRITE32_MEMBER( palette_16bit_dword_le_w );
+ template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift> DECLARE_WRITE32_MEMBER( palette_16bit_dword_be_w );
+
+ // templatized palette writers for 32-bit palette data
+ template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift> DECLARE_WRITE16_MEMBER( palette_32bit_word_le_w );
+ template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift> DECLARE_WRITE16_MEMBER( palette_32bit_word_be_w );
+ template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift> DECLARE_WRITE32_MEMBER( palette_32bit_dword_w );
+
+ // 3-3-2 RGB palette write handlers
+ DECLARE_WRITE8_MEMBER( paletteram_BBGGGRRR_byte_w );
+ DECLARE_WRITE8_MEMBER( paletteram_RRRGGGBB_byte_w );
+ DECLARE_WRITE8_MEMBER( paletteram_BBGGRRII_byte_w );
+
+ // 4-4-4 RGB palette write handlers
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxBBBBGGGGRRRR_byte_le_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxBBBBGGGGRRRR_byte_be_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxBBBBGGGGRRRR_byte_split_lo_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxBBBBGGGGRRRR_byte_split_hi_w );
+ DECLARE_WRITE16_MEMBER( paletteram_xxxxBBBBGGGGRRRR_word_w );
+
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxBBBBRRRRGGGG_byte_le_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxBBBBRRRRGGGG_byte_be_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxBBBBRRRRGGGG_byte_split_lo_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxBBBBRRRRGGGG_byte_split_hi_w );
+ DECLARE_WRITE16_MEMBER( paletteram_xxxxBBBBRRRRGGGG_word_w );
+
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxRRRRBBBBGGGG_byte_split_lo_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxRRRRBBBBGGGG_byte_split_hi_w );
+
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxRRRRGGGGBBBB_byte_le_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxRRRRGGGGBBBB_byte_be_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxRRRRGGGGBBBB_byte_split_lo_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xxxxRRRRGGGGBBBB_byte_split_hi_w );
+ DECLARE_WRITE16_MEMBER( paletteram_xxxxRRRRGGGGBBBB_word_w );
+
+ DECLARE_WRITE8_MEMBER( paletteram_RRRRGGGGBBBBxxxx_byte_be_w );
+ DECLARE_WRITE8_MEMBER( paletteram_RRRRGGGGBBBBxxxx_byte_split_lo_w );
+ DECLARE_WRITE8_MEMBER( paletteram_RRRRGGGGBBBBxxxx_byte_split_hi_w );
+ DECLARE_WRITE16_MEMBER( paletteram_RRRRGGGGBBBBxxxx_word_w );
+
+ // 4-4-4-4 IRGB palette write handlers
+ DECLARE_WRITE16_MEMBER( paletteram_IIIIRRRRGGGGBBBB_word_w );
+ DECLARE_WRITE16_MEMBER( paletteram_RRRRGGGGBBBBIIII_word_w );
+
+ // 5-5-5 RGB palette write handlers
+ DECLARE_WRITE8_MEMBER( paletteram_xBBBBBGGGGGRRRRR_byte_le_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xBBBBBGGGGGRRRRR_byte_be_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xBBBBBGGGGGRRRRR_byte_split_lo_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xBBBBBGGGGGRRRRR_byte_split_hi_w );
+ DECLARE_WRITE16_MEMBER( paletteram_xBBBBBGGGGGRRRRR_word_w );
+
+ DECLARE_WRITE8_MEMBER( paletteram_xBBBBBRRRRRGGGGG_byte_split_lo_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xBBBBBRRRRRGGGGG_byte_split_hi_w );
+
+ DECLARE_WRITE8_MEMBER( paletteram_xRRRRRGGGGGBBBBB_byte_le_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xRRRRRGGGGGBBBBB_byte_be_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xRRRRRGGGGGBBBBB_byte_split_lo_w );
+ DECLARE_WRITE8_MEMBER( paletteram_xRRRRRGGGGGBBBBB_byte_split_hi_w );
+ DECLARE_WRITE16_MEMBER( paletteram_xRRRRRGGGGGBBBBB_word_w );
+ DECLARE_WRITE32_MEMBER( paletteram_xRRRRRGGGGGBBBBB_dword_be_w );
+ DECLARE_WRITE32_MEMBER( paletteram_xRRRRRGGGGGBBBBB_dword_le_w );
+
+ DECLARE_WRITE8_MEMBER( paletteram_xGGGGGRRRRRBBBBB_byte_le_w );
+
+ DECLARE_WRITE16_MEMBER( paletteram_xGGGGGRRRRRBBBBB_word_w );
+ DECLARE_WRITE16_MEMBER( paletteram_xGGGGGBBBBBRRRRR_word_w );
+ DECLARE_WRITE16_MEMBER( paletteram_RRRRRGGGGGBBBBBx_word_w );
+ DECLARE_WRITE16_MEMBER( paletteram_GGGGGRRRRRBBBBBx_word_w );
+ DECLARE_WRITE16_MEMBER( paletteram_RRRRGGGGBBBBRGBx_word_w );
+
+ // 8-8-8 RGB palette write handlers
+ DECLARE_WRITE16_MEMBER( paletteram_xrgb_word_be_w );
+ DECLARE_WRITE16_MEMBER( paletteram_xbgr_word_be_w );
+
+ // generic input port helpers
+ // custom handler
+ DECLARE_CUSTOM_INPUT_MEMBER( custom_port_read );
+
+protected:
+ // helpers called at startup
+ virtual void driver_start();
+ virtual void machine_start();
+ virtual void sound_start();
+ virtual void palette_init();
+ virtual void video_start();
+
+ // helpers called at reset
+ virtual void driver_reset();
+ virtual void machine_reset();
+ virtual void sound_reset();
+ virtual void video_reset();
+
+ // device-level overrides
+ virtual const rom_entry *device_rom_region() const;
+ virtual ioport_constructor device_input_ports() const;
+ virtual void device_start();
+ virtual void device_reset_after_children();
+
+ // internal helpers
+ inline UINT16 paletteram16_le(offs_t offset) const { return m_generic_paletteram_8[offset & ~1] | (m_generic_paletteram_8[offset | 1] << 8); }
+ inline UINT16 paletteram16_be(offs_t offset) const { return m_generic_paletteram_8[offset | 1] | (m_generic_paletteram_8[offset & ~1] << 8); }
+ inline UINT16 paletteram16_split(offs_t offset) const { return m_generic_paletteram_8[offset] | (m_generic_paletteram2_8[offset] << 8); }
+ inline UINT32 paletteram32_be(offs_t offset) const { return m_generic_paletteram_16[offset | 1] | (m_generic_paletteram_16[offset & ~1] << 16); }
+
+public:
+ // generic pointers
+ optional_shared_ptr<UINT8> m_generic_paletteram_8;
+ optional_shared_ptr<UINT8> m_generic_paletteram2_8;
+ optional_shared_ptr<UINT16> m_generic_paletteram_16;
+ optional_shared_ptr<UINT16> m_generic_paletteram2_16;
+ optional_shared_ptr<UINT32> m_generic_paletteram_32;
+ optional_shared_ptr<UINT32> m_generic_paletteram2_32;
+
+private:
+ // helpers
+ void irq_pulse_clear(void *ptr, INT32 param);
+ void soundlatch_sync_callback(void *ptr, INT32 param);
+ void updateflip();
+
+ // internal state
+ const game_driver * m_system; // pointer to the game driver
+ driver_callback_delegate m_callbacks[CB_COUNT]; // start/reset callbacks
+ legacy_callback_func m_legacy_callbacks[CB_COUNT]; // legacy start/reset callbacks
+
+ // generic audio
+ UINT16 m_latch_clear_value;
+ UINT16 m_latched_value[4];
+ UINT8 m_latch_read[4];
+
+ // generic video
+ UINT32 m_flip_screen_x;
+ UINT32 m_flip_screen_y;
+};
+
+
+// this template function creates a stub which constructs a device
+template<class _DriverClass>
+device_t *driver_device_creator(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+{
+ assert(owner == NULL);
+ assert(clock == 0);
+ return global_alloc_clear(_DriverClass(mconfig, &driver_device_creator<_DriverClass>, tag));
+}
+
+
+
+//**************************************************************************
+// PALETTE WRITER TEMPLATES
+//**************************************************************************
+
+// write 8-bit palette data
+template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift>
+WRITE8_MEMBER(driver_device::palette_8bit_byte_w)
+{
+ m_generic_paletteram_8[offset] = data;
+ UINT8 paldata = m_generic_paletteram_8[offset];
+ palette_set_color_rgb(machine(), offset, palexpand<_RedBits>(paldata >> _RedShift), palexpand<_GreenBits>(paldata >> _GreenShift), palexpand<_BlueBits>(paldata >> _BlueShift));
+}
+
+// write 16-bit palette data to consecutive 8-bit addresses with LSB first
+template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift>
+WRITE8_MEMBER(driver_device::palette_16bit_byte_le_w)
+{
+ m_generic_paletteram_8[offset] = data;
+ UINT16 paldata = m_generic_paletteram_8[offset & ~1] | (m_generic_paletteram_8[offset | 1] << 8);
+ palette_set_color_rgb(machine(), offset / 2, palexpand<_RedBits>(paldata >> _RedShift), palexpand<_GreenBits>(paldata >> _GreenShift), palexpand<_BlueBits>(paldata >> _BlueShift));
+}
+
+// write 16-bit palette data to consecutive 8-bit addresses with MSB first
+template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift>
+WRITE8_MEMBER(driver_device::palette_16bit_byte_be_w)
+{
+ m_generic_paletteram_8[offset] = data;
+ UINT16 paldata = m_generic_paletteram_8[offset | 1] | (m_generic_paletteram_8[offset & ~1] << 8);
+ palette_set_color_rgb(machine(), offset / 2, palexpand<_RedBits>(paldata >> _RedShift), palexpand<_GreenBits>(paldata >> _GreenShift), palexpand<_BlueBits>(paldata >> _BlueShift));
+}
+
+// write 16-bit palette data to split 8-bit addresses (LSB)
+template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift>
+WRITE8_MEMBER(driver_device::palette_16bit_byte_split_lo_w)
+{
+ m_generic_paletteram_8[offset] = data;
+ UINT16 paldata = m_generic_paletteram_8[offset] | (m_generic_paletteram2_8[offset] << 8);
+ palette_set_color_rgb(machine(), offset, palexpand<_RedBits>(paldata >> _RedShift), palexpand<_GreenBits>(paldata >> _GreenShift), palexpand<_BlueBits>(paldata >> _BlueShift));
+}
+
+// write 16-bit palette data to split 8-bit addresses (MSB)
+template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift>
+WRITE8_MEMBER(driver_device::palette_16bit_byte_split_hi_w)
+{
+ m_generic_paletteram2_8[offset] = data;
+ UINT16 paldata = m_generic_paletteram_8[offset] | (m_generic_paletteram2_8[offset] << 8);
+ palette_set_color_rgb(machine(), offset, palexpand<_RedBits>(paldata >> _RedShift), palexpand<_GreenBits>(paldata >> _GreenShift), palexpand<_BlueBits>(paldata >> _BlueShift));
+}
+
+// write 16-bit palette data to 16-bit addresses
+template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift>
+WRITE16_MEMBER(driver_device::palette_16bit_word_w)
+{
+ COMBINE_DATA(&m_generic_paletteram_16[offset]);
+ UINT16 paldata = m_generic_paletteram_16[offset];
+ palette_set_color_rgb(machine(), offset, palexpand<_RedBits>(paldata >> _RedShift), palexpand<_GreenBits>(paldata >> _GreenShift), palexpand<_BlueBits>(paldata >> _BlueShift));
+}
+
+// write 16-bit palette data to packed 32-bit addresses (lower entry in lower 16 bits)
+template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift>
+WRITE32_MEMBER(driver_device::palette_16bit_dword_le_w)
+{
+ COMBINE_DATA(&m_generic_paletteram_32[offset]);
+ if (ACCESSING_BITS_0_15)
+ {
+ UINT16 paldata = m_generic_paletteram_32[offset];
+ palette_set_color_rgb(machine(), offset * 2 + 0, palexpand<_RedBits>(paldata >> _RedShift), palexpand<_GreenBits>(paldata >> _GreenShift), palexpand<_GreenBits>(paldata >> _BlueShift));
+ }
+ if (ACCESSING_BITS_16_31)
+ {
+ UINT16 paldata = m_generic_paletteram_32[offset] >> 16;
+ palette_set_color_rgb(machine(), offset * 2 + 1, palexpand<_RedBits>(paldata >> _RedShift), palexpand<_GreenBits>(paldata >> _GreenShift), palexpand<_GreenBits>(paldata >> _BlueShift));
+ }
+}
+
+// write 16-bit palette data to packed 32-bit addresses (lower entry in upper 16 bits)
+template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift>
+WRITE32_MEMBER(driver_device::palette_16bit_dword_be_w)
+{
+ COMBINE_DATA(&m_generic_paletteram_32[offset]);
+ if (ACCESSING_BITS_16_31)
+ {
+ UINT16 paldata = m_generic_paletteram_32[offset] >> 16;
+ palette_set_color_rgb(machine(), offset * 2 + 0, palexpand<_RedBits>(paldata >> _RedShift), palexpand<_GreenBits>(paldata >> _GreenShift), palexpand<_BlueBits>(paldata >> _BlueShift));
+ }
+ if (ACCESSING_BITS_0_15)
+ {
+ UINT16 paldata = m_generic_paletteram_32[offset];
+ palette_set_color_rgb(machine(), offset * 2 + 1, palexpand<_RedBits>(paldata >> _RedShift), palexpand<_GreenBits>(paldata >> _GreenShift), palexpand<_BlueBits>(paldata >> _BlueShift));
+ }
+}
+
+// write 32-bit palette data to consecutive 16-bit addresses with LSW first
+template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift>
+WRITE16_MEMBER(driver_device::palette_32bit_word_le_w)
+{
+ COMBINE_DATA(&m_generic_paletteram_16[offset]);
+ UINT32 paldata = m_generic_paletteram_16[offset & ~1] | (m_generic_paletteram_16[offset | 1] << 16);
+ palette_set_color_rgb(machine(), offset / 2, palexpand<_RedBits>(paldata >> _RedShift), palexpand<_GreenBits>(paldata >> _GreenShift), palexpand<_BlueBits>(paldata >> _BlueShift));
+}
+
+// write 32-bit palette data to consecutive 16-bit addresses with MSW first
+template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift>
+WRITE16_MEMBER(driver_device::palette_32bit_word_be_w)
+{
+ COMBINE_DATA(&m_generic_paletteram_16[offset]);
+ UINT32 paldata = m_generic_paletteram_16[offset | 1] | (m_generic_paletteram_16[offset & ~1] << 16);
+ palette_set_color_rgb(machine(), offset / 2, palexpand<_RedBits>(paldata >> _RedShift), palexpand<_GreenBits>(paldata >> _GreenShift), palexpand<_BlueBits>(paldata >> _BlueShift));
+}
+
+// write 32-bit palette data to 32-bit addresses
+template<int _RedBits, int _GreenBits, int _BlueBits, int _RedShift, int _GreenShift, int _BlueShift>
+WRITE32_MEMBER(driver_device::palette_32bit_dword_w)
+{
+ COMBINE_DATA(&m_generic_paletteram_32[offset]);
+ UINT32 paldata = m_generic_paletteram_32[offset];
+ palette_set_color_rgb(machine(), offset, palexpand<_RedBits>(paldata >> _RedShift), palexpand<_GreenBits>(paldata >> _GreenShift), palexpand<_BlueBits>(paldata >> _BlueShift));
+}
+
+#endif /* __DRIVER_H__ */