mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
mb87078: refactor and correct data_w/r (nw)
This commit is contained in:
parent
a4c222b805
commit
1cc99d3619
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Fabio Priuli,Philip Bennett
|
||||
// copyright-holders:Fabio Priuli, Philip Bennett, hap
|
||||
/*****************************************************************************
|
||||
|
||||
Fujitsu MB87078 6-bit, 4-channel electronic volume controller emulator
|
||||
@ -56,9 +56,9 @@
|
||||
|
||||
/[ 1] D0 /TC [24]
|
||||
| [ 2] D1 /WR [23]
|
||||
MB87078_data_w()| [ 3] D2 /CE [22]
|
||||
MB87078_data_r()| [ 4] D3 DSEL [21]-MB87078_data_w()/data_r() parameter
|
||||
| [ 5] D4 /RESET [20]-MB87078_reset_comp_w()
|
||||
data_w()| [ 3] D2 /CE [22]
|
||||
data_r()| [ 4] D3 DSEL [21]-data_w()/data_r() (offset)
|
||||
(data) | [ 5] D4 /RESET [20]
|
||||
\[ 6] D5 /PD [19]
|
||||
[ 7] DGND VDD [18]
|
||||
[ 8] AGND 1/2 VDD [17]
|
||||
@ -67,51 +67,22 @@
|
||||
[11] AIN1 AOUT2 [14]
|
||||
[12] AOUT1 AIN2 [13]
|
||||
|
||||
|
||||
*****************************************************************************/
|
||||
*****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/mb87078.h"
|
||||
|
||||
|
||||
static const float mb87078_gain_decibel[66] = {
|
||||
0.0, -0.5, -1.0, -1.5, -2.0, -2.5, -3.0, -3.5,
|
||||
-4.0, -4.5, -5.0, -5.5, -6.0, -6.5, -7.0, -7.5,
|
||||
-8.0, -8.5, -9.0, -9.5,-10.0,-10.5,-11.0,-11.5,
|
||||
-12.0,-12.5,-13.0,-13.5,-14.0,-14.5,-15.0,-15.5,
|
||||
-16.0,-16.5,-17.0,-17.5,-18.0,-18.5,-19.0,-19.5,
|
||||
-20.0,-20.5,-21.0,-21.5,-22.0,-22.5,-23.0,-23.5,
|
||||
-24.0,-24.5,-25.0,-25.5,-26.0,-26.5,-27.0,-27.5,
|
||||
-28.0,-28.5,-29.0,-29.5,-30.0,-30.5,-31.0,-31.5,
|
||||
-32.0, -256.0
|
||||
};
|
||||
|
||||
static const int mb87078_gain_percent[66] = {
|
||||
100,94,89,84,79,74,70,66,
|
||||
63,59,56,53,50,47,44,42,
|
||||
39,37,35,33,31,29,28,26,
|
||||
25,23,22,21,19,18,17,16,
|
||||
15,14,14,13,12,11,11,10,
|
||||
10, 9, 8, 8, 7, 7, 7, 6,
|
||||
6, 5, 5, 5, 5, 4, 4, 4,
|
||||
3, 3, 3, 3, 3, 2, 2, 2,
|
||||
2, 0
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
DEVICE INTERFACE
|
||||
*****************************************************************************/
|
||||
|
||||
DEFINE_DEVICE_TYPE(MB87078, mb87078_device, "mb87078", "MB87078 Volume Controller")
|
||||
|
||||
mb87078_device::mb87078_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, MB87078, tag, owner, clock),
|
||||
m_channel_latch(0),
|
||||
m_reset_comp(0),
|
||||
mb87078_device::mb87078_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, MB87078, tag, owner, clock),
|
||||
m_gain_changed_cb(*this)
|
||||
{
|
||||
m_gain[0] = m_gain[1] = m_gain[2] = m_gain[3] = 0;
|
||||
memset(m_latch, 0, sizeof(m_latch));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -122,11 +93,22 @@ void mb87078_device::device_start()
|
||||
{
|
||||
m_gain_changed_cb.resolve_safe();
|
||||
|
||||
m_data = 0;
|
||||
m_control = 0;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
m_gain_index[i] = 0;
|
||||
|
||||
// output volume table, 0dB to -32dB in steps of -0.5dB
|
||||
for (int i = 0; i < (64+1); i++)
|
||||
m_lut_gains[i] = pow(10.0, (-0.5 * i) / 20.0);
|
||||
m_lut_gains[65] = 0.0; // -infinity
|
||||
|
||||
// register for savestates
|
||||
save_item(NAME(m_gain_index));
|
||||
save_item(NAME(m_channel_latch));
|
||||
save_item(NAME(m_reset_comp));
|
||||
save_item(NAME(m_latch[0]));
|
||||
save_item(NAME(m_latch[1]));
|
||||
save_item(NAME(m_gain));
|
||||
save_item(NAME(m_data));
|
||||
save_item(NAME(m_control));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -135,113 +117,60 @@ void mb87078_device::device_start()
|
||||
|
||||
void mb87078_device::device_reset()
|
||||
{
|
||||
m_channel_latch = 0;
|
||||
// all channels enabled, and set at 0dB
|
||||
for (int i = 0; i < 4; i++)
|
||||
m_channel_latch[i] = 0x7f;
|
||||
|
||||
/* reset chip */
|
||||
reset_comp_w(0);
|
||||
reset_comp_w(1);
|
||||
gain_recalc();
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
IMPLEMENTATION
|
||||
*****************************************************************************/
|
||||
|
||||
#define GAIN_MAX_INDEX 64
|
||||
#define GAIN_INFINITY_INDEX 65
|
||||
|
||||
|
||||
static int calc_gain_index( int data0, int data1 )
|
||||
{
|
||||
//data 0: GD0-GD5
|
||||
//data 1: 1 2 4 8 16
|
||||
// c1 c2 EN C0 C32
|
||||
|
||||
if (!(data1 & 0x04))
|
||||
{
|
||||
return GAIN_INFINITY_INDEX;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data1 & 0x10)
|
||||
{
|
||||
return GAIN_MAX_INDEX;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data1 & 0x08)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (data0 ^ 0x3f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mb87078_device::gain_recalc()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int old_index = m_gain[i];
|
||||
m_gain[i] = calc_gain_index(m_latch[0][i], m_latch[1][i]);
|
||||
if (old_index != m_gain[i])
|
||||
m_gain_changed_cb((offs_t)i, mb87078_gain_percent[m_gain[i]]);
|
||||
int gain_index;
|
||||
|
||||
// EN = 0: -infinity dB
|
||||
if (~m_channel_latch[i] & 0x40)
|
||||
gain_index = 65;
|
||||
|
||||
// C32 = 1: -32dB
|
||||
else if (m_channel_latch[i] & 0x100)
|
||||
gain_index = 64;
|
||||
|
||||
// C0 = 1: 0dB
|
||||
else if (m_channel_latch[i] & 0x80)
|
||||
gain_index = 0;
|
||||
|
||||
else
|
||||
gain_index = ~m_channel_latch[i] & 0x3f;
|
||||
|
||||
// callback on change
|
||||
if (gain_index != m_gain_index[i])
|
||||
{
|
||||
m_gain_index[i] = gain_index;
|
||||
m_gain_changed_cb((offs_t)i, gain_percent_r(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void mb87078_device::data_w( int data, int dsel )
|
||||
void mb87078_device::data_w(offs_t offset, u8 data)
|
||||
{
|
||||
if (m_reset_comp == 0)
|
||||
return;
|
||||
if (offset & 1)
|
||||
m_control = data & 0x1f;
|
||||
else
|
||||
m_data = data & 0x3f;
|
||||
|
||||
if (dsel == 0) /* gd0 - gd5 */
|
||||
{
|
||||
m_latch[0][m_channel_latch] = data & 0x3f;
|
||||
}
|
||||
else /* dcs1, dsc2, en, c0, c32, X */
|
||||
{
|
||||
m_channel_latch = data & 3;
|
||||
m_latch[1][m_channel_latch] = data & 0x1f; //always zero bit 5
|
||||
}
|
||||
m_channel_latch[m_control & 3] = (m_control << 4 & 0x1c0) | m_data;
|
||||
gain_recalc();
|
||||
}
|
||||
|
||||
|
||||
float mb87078_device::gain_decibel_r( int channel )
|
||||
u8 mb87078_device::data_r(offs_t offset)
|
||||
{
|
||||
return mb87078_gain_decibel[m_gain[channel]];
|
||||
}
|
||||
|
||||
|
||||
int mb87078_device::gain_percent_r( int channel )
|
||||
{
|
||||
return mb87078_gain_percent[m_gain[channel]];
|
||||
}
|
||||
|
||||
void mb87078_device::reset_comp_w( int level )
|
||||
{
|
||||
m_reset_comp = level;
|
||||
|
||||
/*this seems to be true, according to the datasheets*/
|
||||
if (level == 0)
|
||||
{
|
||||
m_latch[0][0] = 0x3f;
|
||||
m_latch[0][1] = 0x3f;
|
||||
m_latch[0][2] = 0x3f;
|
||||
m_latch[0][3] = 0x3f;
|
||||
|
||||
m_latch[1][0] = 0x0 | 0x4;
|
||||
m_latch[1][1] = 0x1 | 0x4;
|
||||
m_latch[1][2] = 0x2 | 0x4;
|
||||
m_latch[1][3] = 0x3 | 0x4;
|
||||
}
|
||||
|
||||
gain_recalc();
|
||||
return (offset & 1) ? m_control : m_data;
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Fabio Priuli,Philip Bennett
|
||||
// copyright-holders:Fabio Priuli, Philip Bennett, hap
|
||||
/*****************************************************************************
|
||||
|
||||
MB87078 6-bit,4-channel electronic volume controller emulator
|
||||
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAME_MACHINE_MB87078_H
|
||||
@ -19,21 +18,15 @@ public:
|
||||
|
||||
auto gain_changed() { return m_gain_changed_cb.bind(); }
|
||||
|
||||
void data_w(int data, int dsel);
|
||||
void reset_comp_w(int level);
|
||||
|
||||
/* gain_decibel_r will return 'channel' gain on the device.
|
||||
Returned value represents channel gain expressed in decibels,
|
||||
Range from 0 to -32.0 (or -256.0 for -infinity) */
|
||||
float gain_decibel_r(int channel);
|
||||
void data_w(offs_t offset, u8 data);
|
||||
u8 data_r(offs_t offset);
|
||||
|
||||
/* gain_percent_r will return 'channel' gain on the device.
|
||||
Returned value represents channel gain expressed in percents of maximum volume.
|
||||
Range from 100 to 0. (100 = 0dB; 50 = -6dB; 0 = -infinity)
|
||||
This function is designed for use with MAME mixer_xxx() functions. */
|
||||
int gain_percent_r(int channel);
|
||||
|
||||
void gain_recalc();
|
||||
u8 gain_percent_r(offs_t offset) { return gain_factor_r(offset) * 100.0 + 0.5; } // range 100 .. 0
|
||||
double gain_factor_r(offs_t offset) { return m_lut_gains[m_gain_index[offset & 3]]; } // range 1.0 .. 0.0
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -41,11 +34,14 @@ protected:
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
void gain_recalc();
|
||||
double m_lut_gains[64+2];
|
||||
|
||||
// internal state
|
||||
int m_gain[4]; /* gain index 0-63,64,65 */
|
||||
int m_channel_latch; /* current channel */
|
||||
uint8_t m_latch[2][4]; /* 6bit+3bit 4 data latches */
|
||||
uint8_t m_reset_comp;
|
||||
int m_gain_index[4]; // per-channel current index to m_lut_gains
|
||||
u16 m_channel_latch[4];
|
||||
u8 m_control;
|
||||
u8 m_data;
|
||||
|
||||
devcb_write8 m_gain_changed_cb;
|
||||
};
|
||||
|
@ -88,7 +88,7 @@ WRITE16_MEMBER( taito_en_device::en_es5505_bank_w )
|
||||
|
||||
WRITE8_MEMBER( taito_en_device::en_volume_w )
|
||||
{
|
||||
m_mb87078->data_w(data, offset ^ 1);
|
||||
m_mb87078->data_w(offset ^ 1, data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2755,11 +2755,6 @@ TIMER_DEVICE_CALLBACK_MEMBER(namcos22_state::mcu_irq)
|
||||
m_mcu->set_input_line(M37710_LINE_IRQ2, HOLD_LINE);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(namcos22_state::ss22_volume_w)
|
||||
{
|
||||
m_mb87078->data_w(data, offset);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(namcos22_state::mb87078_gain_changed)
|
||||
{
|
||||
m_c352->set_output_gain(offset ^ 3, data / 100.0);
|
||||
@ -2886,7 +2881,7 @@ void namcos22_state::mcu_program(address_map &map)
|
||||
map(0x200000, 0x27ffff).rom().region("mcu", 0);
|
||||
map(0x300000, 0x300001).nopr(); // ? (cybrcycc, alpinesa - writes data to RAM, but then never reads from there)
|
||||
map(0x301000, 0x301001).nopw(); // watchdog? LEDs?
|
||||
map(0x308000, 0x308003).w(FUNC(namcos22_state::ss22_volume_w)).umask16(0x00ff);
|
||||
map(0x308000, 0x308003).w("mb87078", FUNC(mb87078_device::data_w)).umask16(0x00ff);
|
||||
}
|
||||
|
||||
void namcos22_state::mcu_io(address_map &map)
|
||||
|
@ -222,23 +222,6 @@ READ16_MEMBER(taitob_state::trackx_lo_r)
|
||||
return (m_tracky_io[Player]->read() & 0xff) << 8;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(taitob_state::gain_control_w)
|
||||
{
|
||||
if (ACCESSING_BITS_8_15)
|
||||
{
|
||||
if (offset == 0)
|
||||
{
|
||||
m_mb87078->data_w(data >> 8, 0);
|
||||
//logerror("MB87078 dsel=0 data=%4x\n", data);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mb87078->data_w(data >> 8, 1);
|
||||
//logerror("MB87078 dsel=1 data=%4x\n", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(taitob_c_state::realpunc_sensor)
|
||||
{
|
||||
m_maincpu->set_input_line(4, HOLD_LINE);
|
||||
@ -427,7 +410,7 @@ void taitob_state::pbobble_map(address_map &map)
|
||||
map(0x500026, 0x500027).rw(FUNC(taitob_state::eep_latch_r), FUNC(taitob_state::eeprom_w));
|
||||
map(0x500028, 0x500029).w(FUNC(taitob_state::player_34_coin_ctrl_w)); /* simply locks coins 3&4 out */
|
||||
map(0x50002e, 0x50002f).portr("P3_P4_B"); /* shown in service mode, game omits to read it */
|
||||
map(0x600000, 0x600003).w(FUNC(taitob_state::gain_control_w));
|
||||
map(0x600000, 0x600003).w("mb87078", FUNC(mb87078_device::data_w)).umask16(0xff00);
|
||||
map(0x700000, 0x700001).nopr();
|
||||
map(0x700000, 0x700000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
|
||||
map(0x700002, 0x700002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
|
||||
@ -445,7 +428,7 @@ void taitob_state::spacedx_map(address_map &map)
|
||||
map(0x500026, 0x500027).rw(FUNC(taitob_state::eep_latch_r), FUNC(taitob_state::eeprom_w));
|
||||
map(0x500028, 0x500029).w(FUNC(taitob_state::player_34_coin_ctrl_w)); /* simply locks coins 3&4 out */
|
||||
map(0x50002e, 0x50002f).portr("P3_P4_B");
|
||||
map(0x600000, 0x600003).w(FUNC(taitob_state::gain_control_w));
|
||||
map(0x600000, 0x600003).w("mb87078", FUNC(mb87078_device::data_w)).umask16(0xff00);
|
||||
map(0x700000, 0x700001).nopr();
|
||||
map(0x700000, 0x700000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
|
||||
map(0x700002, 0x700002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
|
||||
@ -483,7 +466,7 @@ void taitob_state::qzshowby_map(address_map &map)
|
||||
map(0x600000, 0x600001).nopr();
|
||||
map(0x600000, 0x600000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
|
||||
map(0x600002, 0x600002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
|
||||
map(0x700000, 0x700003).w(FUNC(taitob_state::gain_control_w));
|
||||
map(0x700000, 0x700003).w("mb87078", FUNC(mb87078_device::data_w)).umask16(0xff00);
|
||||
map(0x800000, 0x801fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
|
||||
map(0x900000, 0x90ffff).ram(); /* Main RAM */
|
||||
}
|
||||
|
@ -355,7 +355,6 @@ private:
|
||||
DECLARE_READ32_MEMBER(alpinesa_prot_r);
|
||||
DECLARE_WRITE32_MEMBER(alpinesa_prot_w);
|
||||
DECLARE_WRITE32_MEMBER(namcos22s_chipselect_w);
|
||||
DECLARE_WRITE8_MEMBER(ss22_volume_w);
|
||||
DECLARE_WRITE8_MEMBER(mb87078_gain_changed);
|
||||
DECLARE_WRITE8_MEMBER(mcu_port4_w);
|
||||
DECLARE_READ8_MEMBER(mcu_port4_r);
|
||||
|
@ -66,7 +66,6 @@ protected:
|
||||
template<int Player> DECLARE_READ16_MEMBER(tracky_lo_r);
|
||||
template<int Player> DECLARE_READ16_MEMBER(trackx_hi_r);
|
||||
template<int Player> DECLARE_READ16_MEMBER(trackx_lo_r);
|
||||
DECLARE_WRITE16_MEMBER(gain_control_w);
|
||||
DECLARE_READ16_MEMBER(eep_latch_r);
|
||||
DECLARE_WRITE16_MEMBER(eeprom_w);
|
||||
DECLARE_READ16_MEMBER(player_34_coin_ctrl_r);
|
||||
|
Loading…
Reference in New Issue
Block a user