summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/sound/huc6230.cpp38
-rw-r--r--src/devices/sound/huc6230.h10
-rw-r--r--src/devices/video/huc6272.cpp7
-rw-r--r--src/devices/video/huc6272.h2
4 files changed, 33 insertions, 24 deletions
diff --git a/src/devices/sound/huc6230.cpp b/src/devices/sound/huc6230.cpp
index 07fe59514ed..7969e1c3ae0 100644
--- a/src/devices/sound/huc6230.cpp
+++ b/src/devices/sound/huc6230.cpp
@@ -2,15 +2,17 @@
// copyright-holders:cam900
/*
Hudson HuC6230 SoundBox
- HuC6280 PSG with ADPCM
+ PSG part of HuC6280 with ADPCM
TODO:
- Volume is linear?
- Make it actually working
- - Implement CDDA Volume
+ - Implement/Correct VCA (Voltage Controlled Amplifier) behavior
Related patent:
- https://patents.google.com/patent/US5692099
+ - https://patents.google.com/patent/US6453286
+ - https://patents.google.com/patent/US5548655A
*/
#include "emu.h"
@@ -33,8 +35,8 @@ void huc6230_device::sound_stream_update(sound_stream &stream, stream_sample_t *
if (!channel->m_playing)
continue;
- outputs[0][i] = clamp(outputs[0][i] + ((channel->m_output * channel->m_lvol) >> 2), -32768, 32767);
- outputs[1][i] = clamp(outputs[1][i] + ((channel->m_output * channel->m_rvol) >> 2), -32768, 32767);
+ outputs[0][i] = clamp(outputs[0][i] + ((channel->m_output * channel->m_lvol) >> 3), -32768, 32767);
+ outputs[1][i] = clamp(outputs[1][i] + ((channel->m_output * channel->m_rvol) >> 3), -32768, 32767);
}
}
}
@@ -83,19 +85,19 @@ WRITE8_MEMBER( huc6230_device::write )
}
else if (offset < 0x16)
{
- m_cdda_lvol = data & 0x3f;
- m_cdda_cb(0, m_cdda_lvol);
+ m_pcm_lvol = data & 0x3f;
+ m_vca_cb(0, m_pcm_lvol);
}
else if (offset < 0x17)
{
- m_cdda_rvol = data & 0x3f;
- m_cdda_cb(1, m_cdda_rvol);
+ m_pcm_rvol = data & 0x3f;
+ m_vca_cb(1, m_pcm_rvol);
}
}
TIMER_CALLBACK_MEMBER(huc6230_device::adpcm_timer)
{
- int frq = (1 << m_adpcm_freq);
+ const unsigned frq = (1 << m_adpcm_freq);
for (int adpcm = 0; adpcm < 2; adpcm++)
{
adpcm_channel *channel = &m_adpcm_channel[adpcm];
@@ -113,7 +115,7 @@ TIMER_CALLBACK_MEMBER(huc6230_device::adpcm_timer)
channel->m_pos++;
channel->m_input = m_adpcm_update_cb[adpcm]();
- if (channel->m_pos > frq)
+ if (channel->m_pos >= frq)
{
channel->m_pos = 0;
channel->m_prev_sample = channel->m_curr_sample;
@@ -143,10 +145,10 @@ huc6230_device::huc6230_device(const machine_config &mconfig, const char *tag, d
, m_stream(nullptr)
, m_psg(*this, "psg")
, m_adpcm_freq(0)
- , m_cdda_lvol(0)
- , m_cdda_rvol(0)
+ , m_pcm_lvol(0)
+ , m_pcm_rvol(0)
, m_adpcm_update_cb{{*this}, {*this}}
- , m_cdda_cb(*this)
+ , m_vca_cb(*this)
{
}
@@ -169,9 +171,9 @@ void huc6230_device::device_start()
for (auto &cb : m_adpcm_update_cb)
cb.resolve_safe(0);
- m_cdda_cb.resolve_safe();
+ m_vca_cb.resolve_safe();
- m_stream = machine().sound().stream_alloc(*this, 2, 2, clock() / 96);
+ m_stream = machine().sound().stream_alloc(*this, 2, 2, clock() / 6);
m_adpcm_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(huc6230_device::adpcm_timer),this));
for (int i = 0; i < 2; i++)
@@ -196,13 +198,13 @@ void huc6230_device::device_start()
save_item(NAME(m_adpcm_channel[i].m_input), i);
}
save_item(NAME(m_adpcm_freq));
- save_item(NAME(m_cdda_lvol));
- save_item(NAME(m_cdda_rvol));
+ save_item(NAME(m_pcm_lvol));
+ save_item(NAME(m_pcm_rvol));
}
void huc6230_device::device_clock_changed()
{
- m_stream->set_sample_rate(clock() / 96);
+ m_stream->set_sample_rate(clock() / 6);
attotime adpcm_period = clocks_to_attotime(682);
m_adpcm_timer->adjust(adpcm_period, 0, adpcm_period);
}
diff --git a/src/devices/sound/huc6230.h b/src/devices/sound/huc6230.h
index 6cd26955191..d94c59fcb26 100644
--- a/src/devices/sound/huc6230.h
+++ b/src/devices/sound/huc6230.h
@@ -11,10 +11,12 @@
class huc6230_device : public device_t, public device_sound_interface
{
public:
+ static constexpr feature_type imperfect_features() { return feature::SOUND; } // Incorrect ADPCM
+
huc6230_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <unsigned N> auto adpcm_update_cb() { return m_adpcm_update_cb[N].bind(); }
- auto cdda_cb() { return m_cdda_cb.bind(); }
+ auto vca_callback() { return m_vca_cb.bind(); }
// write only
DECLARE_WRITE8_MEMBER( write );
@@ -48,13 +50,13 @@ private:
required_device<c6280_device> m_psg;
adpcm_channel m_adpcm_channel[2];
uint32_t m_adpcm_freq;
- uint32_t m_cdda_lvol;
- uint32_t m_cdda_rvol;
+ uint32_t m_pcm_lvol;
+ uint32_t m_pcm_rvol;
TIMER_CALLBACK_MEMBER(adpcm_timer);
devcb_read8 m_adpcm_update_cb[2];
- devcb_write8 m_cdda_cb;
+ devcb_write8 m_vca_cb;
};
DECLARE_DEVICE_TYPE(HuC6230, huc6230_device)
diff --git a/src/devices/video/huc6272.cpp b/src/devices/video/huc6272.cpp
index b091b67afb9..d1fca5708ce 100644
--- a/src/devices/video/huc6272.cpp
+++ b/src/devices/video/huc6272.cpp
@@ -10,6 +10,8 @@
ADPCM related patents:
- https://patents.google.com/patent/US5692099
+ - https://patents.google.com/patent/US6453286
+ - https://patents.google.com/patent/US5548655A
***************************************************************************/
@@ -497,9 +499,9 @@ uint8_t huc6272_device::adpcm_update(int chan)
if (!m_adpcm.playing[chan])
return 0;
- int rate = (1 << m_adpcm.rate);
+ const unsigned rate = (1 << m_adpcm.rate);
m_adpcm.pos[chan]++;
- if (m_adpcm.pos[chan] > rate)
+ if (m_adpcm.pos[chan] >= rate)
{
if (m_adpcm.input[chan] == -1)
{
@@ -541,6 +543,7 @@ uint8_t huc6272_device::adpcm_update(int chan)
if (m_adpcm.nibble[chan] >= 28)
m_adpcm.input[chan] = -1;
}
+ m_adpcm.pos[chan] = 0;
}
return (m_adpcm.input[chan] >> m_adpcm.nibble[chan]) & 0xf;
diff --git a/src/devices/video/huc6272.h b/src/devices/video/huc6272.h
index 8d7f0583600..8380482f38b 100644
--- a/src/devices/video/huc6272.h
+++ b/src/devices/video/huc6272.h
@@ -27,6 +27,8 @@ class huc6272_device : public device_t,
public device_memory_interface
{
public:
+ static constexpr feature_type imperfect_features() { return feature::SOUND | feature::GRAPHICS; } // Incorrect ADPCM and Graphics
+
// construction/destruction
huc6272_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);