deco32: Improvements and cleanups

* Emulate LC7535 based volume control for Dragon Gun board based games
* Add DSW3 and DIP locations to Captain Avenger
* Reorganize driver and start cleaning it up (in progress)
This commit is contained in:
Dirk Best 2017-09-22 03:47:59 +02:00
parent 5e8a590c68
commit c7d1aeb956
8 changed files with 1265 additions and 1098 deletions

View File

@ -1445,3 +1445,15 @@ if (SOUNDS["TA7630"]~=null) then
MAME_DIR .. "src/devices/sound/ta7630.h",
}
end
---------------------------------------------------
-- Sanyo LC7535
--@src/devices/sound/lc7535.h,SOUNDS["LC7535"] = true
---------------------------------------------------
if (SOUNDS["LC7535"]~=null) then
files {
MAME_DIR .. "src/devices/sound/lc7535.cpp",
MAME_DIR .. "src/devices/sound/lc7535.h",
}
end

View File

@ -268,6 +268,7 @@ SOUNDS["DAC76"] = true
SOUNDS["TA7630"] = true
SOUNDS["MM5837"] = true
--SOUNDS["DAVE"] = true
SOUNDS["LC7535"] = true
--------------------------------------------------
-- specify available video cores

View File

@ -269,6 +269,7 @@ SOUNDS["MEA8000"] = true
--SOUNDS["DAC76"] = true
--SOUNDS["MM5837"] = true
SOUNDS["DAVE"] = true
--SOUNDS["LC7535"] = true
--------------------------------------------------
-- specify available video cores

View File

@ -0,0 +1,154 @@
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/***************************************************************************
Sanyo LC7535
Electronic Volume/Loudness Control with Serial Data Control
It uses the Sanyo CCB (Computer Control Bus) to communicate. The
device address is 0x08 or 0x09 (depending on the select pin).
***************************************************************************/
#include "emu.h"
#include "lc7535.h"
//**************************************************************************
// CONSTEXPR DEFINITIONS
//**************************************************************************
constexpr int lc7535_device::m_5db[];
constexpr int lc7535_device::m_1db[];
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(LC7535, lc7535_device, "lc7535", "Sanyo LC7535")
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// lc7535_device - constructor
//-------------------------------------------------
lc7535_device::lc7535_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, LC7535, tag, owner, clock),
m_select_cb(*this),
m_addr(0), m_data(0),
m_count(0),
m_ce(0), m_di(0), m_clk(0)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void lc7535_device::device_start()
{
// resolve callbacks
m_select_cb.resolve();
m_volume_cb.bind_relative_to(*owner());
// register for save states
save_item(NAME(m_addr));
save_item(NAME(m_data));
save_item(NAME(m_count));
save_item(NAME(m_ce));
save_item(NAME(m_di));
save_item(NAME(m_clk));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void lc7535_device::device_reset()
{
}
//-------------------------------------------------
// normalize - convert attenuation to range 0-1
//-------------------------------------------------
float lc7535_device::normalize(int attenuation)
{
return (attenuation + (MAX * (-1.0))) / (MAX * (-1.0));
}
//**************************************************************************
// INTERFACE
//**************************************************************************
WRITE_LINE_MEMBER( lc7535_device::ce_w )
{
m_ce = state;
}
WRITE_LINE_MEMBER( lc7535_device::di_w )
{
m_di = state;
}
WRITE_LINE_MEMBER( lc7535_device::clk_w )
{
if (m_clk == 0 && state == 1)
{
if (m_ce == 0)
{
if (m_count == 0)
m_addr = 0;
m_addr <<= 1;
m_addr |= m_di;
if (++m_count == 4)
{
m_addr = bitswap(m_addr, 0, 1, 2, 3);
m_count = 0;
}
}
else
{
// our address is either 8 or 9
if (m_addr == (8 | (m_select_cb() ? 0 : 1)))
{
m_data <<= 1;
m_data |= m_di;
if (++m_count == 16)
{
m_data = bitswap(m_data, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
// right channel
int att_r = m_1db[(m_data >> 4) & 0x07];
if (att_r != MAX)
att_r += m_5db[(m_data >> 0) & 0x0f];
// left channel
int att_l = m_1db[(m_data >> 12) & 0x07];
if (att_l != MAX)
att_l += m_5db[(m_data >> 8) & 0x0f];
bool loudness = bool(BIT(m_data, 7));
if (!m_volume_cb.isnull())
m_volume_cb(att_r, att_l, loudness);
m_addr = 0;
m_count = 0;
}
}
}
}
m_clk = state;
}

View File

@ -0,0 +1,96 @@
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/***************************************************************************
Sanyo LC7535
Electronic Volume/Loudness Control with Serial Data Control
___ ___
L5dBIN 1 |* u | 22 R5dBIN
LCT1 2 | | 21 RCT1
LCT2 3 | | 20 RCT2
L5dBOUT 4 | | 19 R5dBOUT
L1dBIN 5 | | 18 R1dBIN
L1dBOUT 6 |LC7535P| 17 R1dBOUT
LVM 7 | | 16 RVM
VEE 8 | | 16 VCC
S 9 | | 14 CE
VDD 10 | | 13 DI
VSS 11 |_______| 12 CLK
***************************************************************************/
#ifndef MAME_SOUND_LC7535_H
#define MAME_SOUND_LC7535_H
#pragma once
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_LC7535_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, LC7535, 0)
#define MCFG_LC7535_SELECT_CB(_read) \
devcb = &lc7535_device::set_select_callback(*device, DEVCB_##_read);
#define MCFG_LC7535_VOLUME_CB(_class, _method) \
lc7535_device::set_volume_callback(*device, lc7535_device::volume_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner)));
#define LC7535_VOLUME_CHANGED(name) void name(int attenuation_right, int attenuation_left, bool loudness)
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class lc7535_device : public device_t
{
public:
// construction/destruction
lc7535_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
typedef device_delegate<void (int attenuation_right, int attenuation_left, bool loudness)> volume_delegate;
static void set_volume_callback(device_t &device, volume_delegate &&cb)
{ downcast<lc7535_device &>(device).m_volume_cb = std::move(cb); }
template <class Object> static devcb_base &set_select_callback(device_t &device, Object &&cb)
{ return downcast<lc7535_device &>(device).m_select_cb.set_callback(std::forward<Object>(cb)); }
// serial interface
DECLARE_WRITE_LINE_MEMBER( ce_w );
DECLARE_WRITE_LINE_MEMBER( di_w );
DECLARE_WRITE_LINE_MEMBER( clk_w );
float normalize(int attenuation);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
private:
// maximum attenuation is -98 dB for infinity
enum { MAX = -98 };
static constexpr int m_5db[16] = { -75, -70, -65, -60, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, -0 };
static constexpr int m_1db[8] = { MAX, MAX, -4, -3, -2, -1, 0, MAX };
// callbacks
devcb_read_line m_select_cb;
volume_delegate m_volume_cb;
// state
uint8_t m_addr;
uint16_t m_data;
int m_count, m_ce, m_di, m_clk;
};
// device type definition
DECLARE_DEVICE_TYPE(LC7535, lc7535_device)
#endif // MAME_SOUND_LC7535_H

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@
#include "machine/deco_irq.h"
#include "machine/eepromser.h"
#include "machine/gen_latch.h"
#include "sound/lc7535.h"
#include "sound/okim6295.h"
#include "sound/ym2151.h"
#include "machine/deco146.h"
@ -77,7 +78,7 @@ public:
required_shared_ptr<uint32_t> m_pf2_rowscroll32;
required_shared_ptr<uint32_t> m_pf3_rowscroll32;
required_shared_ptr<uint32_t> m_pf4_rowscroll32;
required_shared_ptr<uint32_t> m_generic_paletteram_32;
optional_shared_ptr<uint32_t> m_generic_paletteram_32;
optional_shared_ptr<uint32_t> m_ace_ram;
uint8_t m_nslasher_sound_irq; // nslasher and lockload
@ -103,6 +104,15 @@ public:
uint16_t m_pf4_rowscroll[0x1000]; // common
// common
DECLARE_READ16_MEMBER(deco_104_r);
DECLARE_WRITE16_MEMBER(deco_104_w);
DECLARE_READ16_MEMBER(deco_146_r);
DECLARE_WRITE16_MEMBER(deco_146_w);
DECLARE_READ8_MEMBER(eeprom_r);
DECLARE_WRITE8_MEMBER(eeprom_w);
DECLARE_WRITE8_MEMBER(volume_w);
DECLARE_WRITE32_MEMBER(vblank_ack_w);
DECLARE_WRITE32_MEMBER(pf1_rowscroll_w);
DECLARE_WRITE32_MEMBER(pf2_rowscroll_w);
DECLARE_WRITE32_MEMBER(pf3_rowscroll_w);
@ -111,19 +121,15 @@ public:
// captaven
DECLARE_READ32_MEMBER(_71_r);
DECLARE_READ32_MEMBER(captaven_soundcpu_r);
DECLARE_WRITE32_MEMBER(nonbuffered_palette_w);
DECLARE_READ8_MEMBER(captaven_dsw1_r);
DECLARE_READ8_MEMBER(captaven_dsw2_r);
DECLARE_READ8_MEMBER(captaven_dsw3_r);
DECLARE_READ8_MEMBER(captaven_soundcpu_status_r);
// fghthist
DECLARE_WRITE32_MEMBER(sound_w);
DECLARE_READ32_MEMBER(fghthist_control_r);
DECLARE_WRITE32_MEMBER(fghthist_eeprom_w);
DECLARE_READ32_MEMBER(fghthist_protection_region_0_146_r);
DECLARE_WRITE32_MEMBER(fghthist_protection_region_0_146_w);
DECLARE_WRITE32_MEMBER(vblank_ack_w);
// nslasher
DECLARE_WRITE32_MEMBER(nslasher_eeprom_w);
DECLARE_READ16_MEMBER(fghthist_in0_r);
DECLARE_READ16_MEMBER(fghthist_in1_r);
// tattass
DECLARE_WRITE32_MEMBER(tattass_control_w);
@ -133,8 +139,6 @@ public:
DECLARE_READ8_MEMBER(latch_r);
// nslasher and tattass
DECLARE_READ16_MEMBER(nslasher_protection_region_0_104_r);
DECLARE_WRITE16_MEMBER(nslasher_protection_region_0_104_w);
DECLARE_READ16_MEMBER(nslasher_debug_r);
DECLARE_READ32_MEMBER(spriteram2_r);
DECLARE_WRITE32_MEMBER(spriteram2_w);
@ -151,11 +155,6 @@ public:
DECLARE_WRITE32_MEMBER(buffered_palette_w);
DECLARE_WRITE32_MEMBER(palette_dma_w);
// captaven, dragongun and lockload
DECLARE_READ16_MEMBER(dg_protection_region_0_146_r);
DECLARE_WRITE16_MEMBER(dg_protection_region_0_146_w);
virtual void video_start() override;
DECLARE_DRIVER_INIT(tattass);
DECLARE_DRIVER_INIT(nslasher);
DECLARE_DRIVER_INIT(captaven);
@ -175,12 +174,15 @@ public:
void nslasher_sound_cb( address_space &space, uint16_t data, uint16_t mem_mask );
DECLARE_READ16_MEMBER(port_b_tattass);
void tattass_sound_cb( address_space &space, uint16_t data, uint16_t mem_mask );
void deco32_set_audio_output(uint8_t raw_data);
DECO16IC_BANK_CB_MEMBER(fghthist_bank_callback);
DECO16IC_BANK_CB_MEMBER(captaven_bank_callback);
DECO16IC_BANK_CB_MEMBER(tattass_bank_callback);
DECOSPR_PRIORITY_CB_MEMBER(captaven_pri_callback);
protected:
virtual void video_start() override;
};
class dragngun_state : public deco32_state
@ -191,13 +193,20 @@ public:
m_sprite_layout_0_ram(*this, "lay0"),
m_sprite_layout_1_ram(*this, "lay1"),
m_sprite_lookup_0_ram(*this, "look0"),
m_sprite_lookup_1_ram(*this, "look1")
m_sprite_lookup_1_ram(*this, "look1"),
m_oki3(*this, "oki3"),
m_vol_main(*this, "vol_main"),
m_vol_gun(*this, "vol_gun"),
m_gun_speaker_disabled(true)
{ }
required_shared_ptr<uint32_t> m_sprite_layout_0_ram;
required_shared_ptr<uint32_t> m_sprite_layout_1_ram;
required_shared_ptr<uint32_t> m_sprite_lookup_0_ram;
required_shared_ptr<uint32_t> m_sprite_lookup_1_ram;
optional_device<okim6295_device> m_oki3;
required_device<lc7535_device> m_vol_main;
required_device<lc7535_device> m_vol_gun;
uint32_t m_sprite_ctrl;
int m_lightgun_port;
@ -209,11 +218,14 @@ public:
DECLARE_WRITE32_MEMBER(spriteram_dma_w);
DECLARE_WRITE32_MEMBER(gun_irq_ack_w);
DECLARE_READ32_MEMBER(unk_video_r);
DECLARE_READ32_MEMBER(service_r);
DECLARE_READ32_MEMBER(eeprom_r);
DECLARE_WRITE32_MEMBER(eeprom_w);
DECLARE_WRITE8_MEMBER(eeprom_w);
DECLARE_READ32_MEMBER(lockload_gun_mirror_r);
DECLARE_WRITE32_MEMBER(volume_w);
DECLARE_WRITE32_MEMBER(speaker_switch_w);
LC7535_VOLUME_CHANGED(volume_main_changed);
LC7535_VOLUME_CHANGED(volume_gun_changed);
virtual void video_start() override;
DECLARE_DRIVER_INIT(dragngun);
DECLARE_DRIVER_INIT(dragngunj);
@ -227,4 +239,7 @@ public:
DECO16IC_BANK_CB_MEMBER(bank_1_callback);
DECO16IC_BANK_CB_MEMBER(bank_2_callback);
private:
bool m_gun_speaker_disabled;
};

View File

@ -98,19 +98,6 @@ void deco32_state::updateAceRam()
/* Later games have double buffered paletteram - the real palette ram is
only updated on a DMA call */
WRITE32_MEMBER(deco32_state::nonbuffered_palette_w)
{
int r,g,b;
COMBINE_DATA(&m_generic_paletteram_32[offset]);
b = (m_generic_paletteram_32[offset] >>16) & 0xff;
g = (m_generic_paletteram_32[offset] >> 8) & 0xff;
r = (m_generic_paletteram_32[offset] >> 0) & 0xff;
m_palette->set_pen_color(offset,rgb_t(r,g,b));
}
WRITE32_MEMBER(deco32_state::buffered_palette_w)
{
COMBINE_DATA(&m_generic_paletteram_32[offset]);