diff options
Diffstat (limited to 'src/devices/machine/mb87078.cpp')
-rw-r--r-- | src/devices/machine/mb87078.cpp | 183 |
1 files changed, 56 insertions, 127 deletions
diff --git a/src/devices/machine/mb87078.cpp b/src/devices/machine/mb87078.cpp index 4213dcb269a..0380975ee62 100644 --- a/src/devices/machine/mb87078.cpp +++ b/src/devices/machine/mb87078.cpp @@ -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; -void mb87078_device::data_w( int data, int dsel ) -{ - if (m_reset_comp == 0) - return; + // C0 = 1: 0dB + else if (m_channel_latch[i] & 0x80) + gain_index = 0; - 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 + 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)); + } } - gain_recalc(); } - -float mb87078_device::gain_decibel_r( int channel ) +void mb87078_device::data_w(offs_t offset, u8 data) { - return mb87078_gain_decibel[m_gain[channel]]; -} - + if (offset & 1) + m_control = data & 0x1f; + else + m_data = data & 0x3f; -int mb87078_device::gain_percent_r( int channel ) -{ - return mb87078_gain_percent[m_gain[channel]]; + m_channel_latch[m_control & 3] = (m_control << 4 & 0x1c0) | m_data; + gain_recalc(); } -void mb87078_device::reset_comp_w( int level ) +u8 mb87078_device::data_r(offs_t offset) { - 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; } |