diff options
Diffstat (limited to 'src/devices/machine/k054321.cpp')
-rw-r--r-- | src/devices/machine/k054321.cpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/devices/machine/k054321.cpp b/src/devices/machine/k054321.cpp new file mode 100644 index 00000000000..54c32172b37 --- /dev/null +++ b/src/devices/machine/k054321.cpp @@ -0,0 +1,138 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +/***************************************************************************/ +/* */ +/* 054321 / 054544 / 054986A */ +/* */ +/* Konami sound control chip */ +/* */ +/***************************************************************************/ + +/* + The 054321 is a sound communication latch/volume manager chip, that + is integrated into the 054544 and 05489A hybrid chips. The hybrid + chips also include the DACs, capacitors, etc needed for the audio + output. + + The 054321 manages three latches (maybe four) to allow communication + between the main cpu and the soud cpu, and provides two independant + busses to ensure decoupling. It also manages one global volume and + a per-channel mute for two channels. + + Volume setting is a little strange, with one address to reset it to + zero and another to increment it by one. Accepted volume range + seems to be 1-60, with 40 for "normal". + + The chip seems to be an intermediate step between the 053260 + (full-on sound chip with dual busses and internal latches for + communication) and the 056800 (MIRAC, similar to the 054321 but + 4-channel). +*/ + +#include "emu.h" +#include "k054321.h" + +#include <math.h> + +const device_type K054321 = device_creator<k054321_device>; + +DEVICE_ADDRESS_MAP_START(main_map, 8, k054321_device) + AM_RANGE(0x0, 0x0) AM_WRITE(active_w) + AM_RANGE(0x2, 0x2) AM_WRITE(volume_reset_w) + AM_RANGE(0x3, 0x3) AM_WRITE(volume_up_w) + AM_RANGE(0x4, 0x4) AM_WRITE(dummy_w) + AM_RANGE(0x6, 0x6) AM_WRITE(main1_w) + AM_RANGE(0x7, 0x7) AM_WRITE(main2_w) + AM_RANGE(0x8, 0x8) AM_READ(busy_r) + AM_RANGE(0xa, 0xa) AM_READ(sound1_r) +ADDRESS_MAP_END + +DEVICE_ADDRESS_MAP_START(sound_map, 8, k054321_device) + AM_RANGE(0x0, 0x0) AM_WRITE(sound1_w) + AM_RANGE(0x2, 0x2) AM_READ(main1_r) + AM_RANGE(0x3, 0x3) AM_READ(main2_r) +ADDRESS_MAP_END + +k054321_device::k054321_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, K054321, "K053421 Maincpu-Soundcpu interface", tag, owner, clock, "k054321", __FILE__), + m_left(*this, finder_base::DUMMY_TAG), + m_right(*this, finder_base::DUMMY_TAG) +{ +} + +void k054321_device::set_gain_devices(const char *_left, const char *_right) +{ + m_left.set_tag(_left); + m_right.set_tag(_right); +} + +void k054321_device::device_start() +{ +} + +READ8_MEMBER( k054321_device::main1_r) +{ + return m_main1; +} + +WRITE8_MEMBER(k054321_device::main1_w) +{ + m_main1 = data; +} + +READ8_MEMBER( k054321_device::main2_r) +{ + return m_main2; +} + +WRITE8_MEMBER(k054321_device::main2_w) +{ + m_main2 = data; +} + +READ8_MEMBER( k054321_device::sound1_r) +{ + return m_sound1; +} + +WRITE8_MEMBER(k054321_device::sound1_w) +{ + m_sound1 = data; +} + +WRITE8_MEMBER(k054321_device::volume_reset_w) +{ + m_volume = 0; + propagate_volume(); +} + +WRITE8_MEMBER(k054321_device::volume_up_w) +{ + m_volume ++; + propagate_volume(); +} + +READ8_MEMBER(k054321_device::busy_r) +{ + return 0; // bit0 = 1 means busy +} + +WRITE8_MEMBER(k054321_device::active_w) +{ + m_active = data; + propagate_volume(); +} + +WRITE8_MEMBER(k054321_device::dummy_w) +{ + if(data != 0x4a) + logerror("unexpected dummy_w %02x\n", data); +} + +void k054321_device::propagate_volume() +{ + double vol = pow(2, (m_volume - 40)/10.0); + m_left->set_input_gain(0, m_active & 2 ? vol : 0.0); + m_right->set_input_gain(0, m_active & 1 ? vol : 0.0); +} |