/*************************************************************************** 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 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 static void driver_init_wrapper(running_machine &machine) { (machine.driver_data<_DriverClass>()->*_Function)(); } void init_0() {}; // 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 UINT32 soundlatch_read(UINT8 index = 0); 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 void soundlatch_write(UINT8 index, UINT32 data); void soundlatch_write(UINT32 data) { soundlatch_write(0, data); } 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 void soundlatch_clear(UINT8 index = 0); 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 DECLARE_WRITE8_MEMBER( palette_8bit_byte_w ); // templatized palette writers for 16-bit palette data template DECLARE_WRITE8_MEMBER( palette_16bit_byte_le_w ); template DECLARE_WRITE8_MEMBER( palette_16bit_byte_be_w ); template DECLARE_WRITE8_MEMBER( palette_16bit_byte_split_lo_w ); template DECLARE_WRITE8_MEMBER( palette_16bit_byte_split_hi_w ); template DECLARE_WRITE16_MEMBER( palette_16bit_word_w ); template DECLARE_WRITE32_MEMBER( palette_16bit_dword_le_w ); template DECLARE_WRITE32_MEMBER( palette_16bit_dword_be_w ); // templatized palette writers for 32-bit palette data template DECLARE_WRITE16_MEMBER( palette_32bit_word_le_w ); template DECLARE_WRITE16_MEMBER( palette_32bit_word_be_w ); template 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 m_generic_paletteram_8; optional_shared_ptr m_generic_paletteram2_8; optional_shared_ptr m_generic_paletteram_16; optional_shared_ptr m_generic_paletteram2_16; optional_shared_ptr m_generic_paletteram_32; optional_shared_ptr 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 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 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 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 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 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 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 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 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 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 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 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 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__ */