summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author cam900 <dbtlrchl@naver.com>2018-09-03 11:31:52 +0900
committer ajrhacker <ajrhacker@users.noreply.github.com>2018-09-02 22:31:52 -0400
commitb8c8f9423aac5ea785f5e67df996c97392db2509 (patch)
tree8e1721d113aa74d3f92647fdb36f17831c84e35a /src
parent8029c10d4f13e0606bb933af7d4a3c27ee553a5b (diff)
huc6230.cpp : Fix PSG, Timer'd ADPCM update, Implement CD-DA Volume (#3919)
huc6272.cpp : Make CD-DA Playable
Diffstat (limited to 'src')
-rw-r--r--src/devices/sound/huc6230.cpp88
-rw-r--r--src/devices/sound/huc6230.h6
-rw-r--r--src/devices/video/huc6272.cpp21
-rw-r--r--src/devices/video/huc6272.h8
-rw-r--r--src/mame/drivers/pcfx.cpp1
5 files changed, 97 insertions, 27 deletions
diff --git a/src/devices/sound/huc6230.cpp b/src/devices/sound/huc6230.cpp
index 9b77d1f83c0..ce5ee4b3e2e 100644
--- a/src/devices/sound/huc6230.cpp
+++ b/src/devices/sound/huc6230.cpp
@@ -18,17 +18,11 @@ constexpr int clamp(int val, int min, int max) { return std::min(max, std::max(m
void huc6230_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
- int frq = (1 << m_adpcm_freq);
for (int i = 0; i < samples; i++)
{
outputs[0][i] = inputs[0][i];
outputs[1][i] = inputs[1][i];
- int cdda_l = inputs[2][i];
- int cdda_r = inputs[3][i];
- outputs[0][i] = clamp(outputs[0][i] + ((cdda_l * m_cdda_lvol) >> 6), -32768, 32767);
- outputs[1][i] = clamp(outputs[1][i] + ((cdda_r * m_cdda_rvol) >> 6), -32768, 32767);
-
for (int adpcm = 0; adpcm < 2; adpcm++)
{
adpcm_channel *channel = &m_adpcm_channel[adpcm];
@@ -36,25 +30,8 @@ void huc6230_device::sound_stream_update(sound_stream &stream, stream_sample_t *
if (!channel->m_playing)
continue;
- int32_t sample;
-
- channel->m_pos++;
- channel->m_input = m_adpcm_update_cb[adpcm]();
-
- if (channel->m_pos > frq)
- {
- channel->m_pos = 0;
- channel->m_prev_sample = channel->m_curr_sample;
- channel->m_curr_sample = channel->m_adpcm.clock(channel->m_input & 0xf);
- }
- if (!channel->m_interpolate)
- sample = channel->m_curr_sample;
- else
- sample = ((channel->m_prev_sample * (frq - channel->m_pos)) +
- (channel->m_curr_sample * channel->m_pos)) >> m_adpcm_freq;
-
- outputs[0][i] = clamp(outputs[0][i] + ((sample * channel->m_lvol) >> 2), -32768, 32767);
- outputs[1][i] = clamp(outputs[1][i] + ((sample * channel->m_rvol) >> 2), -32768, 32767);
+ 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);
}
}
}
@@ -84,6 +61,7 @@ WRITE8_MEMBER( huc6230_device::write )
m_adpcm_channel[i].m_playing = 0;
m_adpcm_channel[i].m_prev_sample = 0;
m_adpcm_channel[i].m_curr_sample = 0;
+ m_adpcm_channel[i].m_output = 0;
m_adpcm_channel[i].m_pos = 0;
}
else
@@ -101,9 +79,57 @@ WRITE8_MEMBER( huc6230_device::write )
m_adpcm_channel[offset >> 1].m_rvol = data & 0x3f;
}
else if (offset < 0x16)
+ {
m_cdda_lvol = data & 0x3f;
+ m_cdda_cb(0, m_cdda_lvol);
+ }
else if (offset < 0x17)
+ {
m_cdda_rvol = data & 0x3f;
+ m_cdda_cb(1, m_cdda_rvol);
+ }
+}
+
+TIMER_CALLBACK_MEMBER(huc6230_device::adpcm_timer)
+{
+ int frq = (1 << m_adpcm_freq);
+ for (int adpcm = 0; adpcm < 2; adpcm++)
+ {
+ adpcm_channel *channel = &m_adpcm_channel[adpcm];
+
+ if (!channel->m_playing)
+ {
+ if (channel->m_output != 0)
+ {
+ m_stream->update();
+ channel->m_output = 0;
+ }
+ continue;
+ }
+
+ channel->m_pos++;
+ channel->m_input = m_adpcm_update_cb[adpcm]();
+
+ if (channel->m_pos > frq)
+ {
+ channel->m_pos = 0;
+ channel->m_prev_sample = channel->m_curr_sample;
+ channel->m_curr_sample = channel->m_adpcm.clock(channel->m_input & 0xf);
+ }
+
+ int32_t new_output;
+ if (!channel->m_interpolate)
+ new_output = channel->m_curr_sample;
+ else
+ new_output = ((channel->m_prev_sample * (frq - channel->m_pos)) +
+ (channel->m_curr_sample * channel->m_pos)) >> m_adpcm_freq;
+
+ if (channel->m_output != new_output)
+ {
+ m_stream->update();
+ channel->m_output = new_output;
+ }
+ }
}
DEFINE_DEVICE_TYPE(HuC6230, huc6230_device, "huc6230", "Hudson Soft HuC6230 SoundBox")
@@ -117,6 +143,7 @@ huc6230_device::huc6230_device(const machine_config &mconfig, const char *tag, d
, m_cdda_lvol(0)
, m_cdda_rvol(0)
, m_adpcm_update_cb{{*this}, {*this}}
+ , m_cdda_cb(*this)
{
}
@@ -139,13 +166,17 @@ void huc6230_device::device_start()
for (auto &cb : m_adpcm_update_cb)
cb.resolve_safe(0);
- m_stream = machine().sound().stream_alloc(*this, 4, 2, clock() / 682); // or /672?
+ m_cdda_cb.resolve_safe();
+
+ m_stream = machine().sound().stream_alloc(*this, 2, 2, clock() / 96);
+ m_adpcm_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(huc6230_device::adpcm_timer),this));
for (int i = 0; i < 2; i++)
{
m_adpcm_channel[i].m_playing = 0;
m_adpcm_channel[i].m_prev_sample = 0;
m_adpcm_channel[i].m_curr_sample = 0;
+ m_adpcm_channel[i].m_output = 0;
m_adpcm_channel[i].m_pos = 0;
m_adpcm_channel[i].m_input = 0;
@@ -157,6 +188,7 @@ void huc6230_device::device_start()
save_item(NAME(m_adpcm_channel[i].m_playing), i);
save_item(NAME(m_adpcm_channel[i].m_prev_sample), i);
save_item(NAME(m_adpcm_channel[i].m_curr_sample), i);
+ save_item(NAME(m_adpcm_channel[i].m_output), i);
save_item(NAME(m_adpcm_channel[i].m_pos), i);
save_item(NAME(m_adpcm_channel[i].m_input), i);
}
@@ -167,5 +199,7 @@ void huc6230_device::device_start()
void huc6230_device::device_clock_changed()
{
- m_stream->set_sample_rate(clock() / 682);
+ m_stream->set_sample_rate(clock() / 96);
+ 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 632dbee80de..6cd26955191 100644
--- a/src/devices/sound/huc6230.h
+++ b/src/devices/sound/huc6230.h
@@ -14,6 +14,7 @@ public:
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(); }
// write only
DECLARE_WRITE8_MEMBER( write );
@@ -36,19 +37,24 @@ private:
uint8_t m_playing;
int32_t m_prev_sample;
int32_t m_curr_sample;
+ int32_t m_output;
uint32_t m_pos;
uint8_t m_input;
};
// internal state
sound_stream *m_stream;
+ emu_timer *m_adpcm_timer;
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;
+ TIMER_CALLBACK_MEMBER(adpcm_timer);
+
devcb_read8 m_adpcm_update_cb[2];
+ devcb_write8 m_cdda_cb;
};
DECLARE_DEVICE_TYPE(HuC6230, huc6230_device)
diff --git a/src/devices/video/huc6272.cpp b/src/devices/video/huc6272.cpp
index 8fd271afc0a..c6e94bb9810 100644
--- a/src/devices/video/huc6272.cpp
+++ b/src/devices/video/huc6272.cpp
@@ -47,6 +47,8 @@ huc6272_device::huc6272_device(const machine_config &mconfig, const char *tag, d
: device_t(mconfig, HUC6272, tag, owner, clock),
device_memory_interface(mconfig, *this),
m_huc6271(*this, finder_base::DUMMY_TAG),
+ m_cdda_l(*this, "cdda_l"),
+ m_cdda_r(*this, "cdda_r"),
m_program_space_config("microprg", ENDIANNESS_LITTLE, 16, 4, 0, address_map_constructor(), address_map_constructor(FUNC(huc6272_device::microprg_map), this)),
m_data_space_config("kram", ENDIANNESS_LITTLE, 32, 21, 0, address_map_constructor(), address_map_constructor(FUNC(huc6272_device::kram_map), this)),
m_microprg_ram(*this, "microprg_ram"),
@@ -547,6 +549,14 @@ READ8_MEMBER(huc6272_device::adpcm_update_1)
return adpcm_update(1);
}
+WRITE8_MEMBER(huc6272_device::cdda_update)
+{
+ if (offset)
+ m_cdda_r->set_output_gain(ALL_OUTPUTS, float(data) / 63.0);
+ else
+ m_cdda_l->set_output_gain(ALL_OUTPUTS, float(data) / 63.0);
+}
+
void huc6272_device::interrupt_update()
{
if (m_adpcm.interrupt)
@@ -555,12 +565,22 @@ void huc6272_device::interrupt_update()
m_irq_changed_cb(CLEAR_LINE);
}
+void huc6272_device::cdrom_config(device_t *device)
+{
+ device = device->subdevice("cdda");
+ MCFG_SOUND_ROUTE(0, "^^cdda_l", 1.0)
+ MCFG_SOUND_ROUTE(1, "^^cdda_r", 1.0)
+}
+
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void huc6272_device::device_add_mconfig(machine_config &config)
{
+ SPEAKER(config, m_cdda_l).front_left();
+ SPEAKER(config, m_cdda_r).front_right();
+
scsi_port_device &scsibus(SCSI_PORT(config, "scsi"));
scsibus.set_data_input_buffer("scsi_data_in");
scsibus.rst_handler().set("scsi_ctrl_in", FUNC(input_buffer_device::write_bit7));
@@ -578,4 +598,5 @@ void huc6272_device::device_add_mconfig(machine_config &config)
INPUT_BUFFER(config, "scsi_data_in");
scsibus.set_slot_device(1, "cdrom", SCSICD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_1));
+ scsibus.slot(1).set_option_machine_config("cdrom", cdrom_config);
}
diff --git a/src/devices/video/huc6272.h b/src/devices/video/huc6272.h
index a20b94e530e..cd931a1dae9 100644
--- a/src/devices/video/huc6272.h
+++ b/src/devices/video/huc6272.h
@@ -14,6 +14,7 @@
#include "bus/scsi/scsi.h"
#include "bus/scsi/scsicd.h"
#include "video/huc6271.h"
+#include "speaker.h"
//**************************************************************************
@@ -51,6 +52,11 @@ public:
DECLARE_READ8_MEMBER( adpcm_update_0 );
DECLARE_READ8_MEMBER( adpcm_update_1 );
+ // CD-DA operations
+ DECLARE_WRITE8_MEMBER( cdda_update );
+
+ static void cdrom_config(device_t *device);
+
protected:
// device-level overrides
virtual void device_validity_check(validity_checker &valid) const override;
@@ -61,6 +67,8 @@ protected:
private:
required_device<huc6271_device> m_huc6271;
+ required_device<speaker_device> m_cdda_l;
+ required_device<speaker_device> m_cdda_r;
uint8_t m_register;
uint32_t m_kram_addr_r, m_kram_addr_w;
diff --git a/src/mame/drivers/pcfx.cpp b/src/mame/drivers/pcfx.cpp
index 5a38480311f..4562f434752 100644
--- a/src/mame/drivers/pcfx.cpp
+++ b/src/mame/drivers/pcfx.cpp
@@ -454,6 +454,7 @@ MACHINE_CONFIG_START(pcfx_state::pcfx)
huc6230_device &huc6230(HuC6230(config, "huc6230", XTAL(21'477'272)));
huc6230.adpcm_update_cb<0>().set("huc6272", FUNC(huc6272_device::adpcm_update_0));
huc6230.adpcm_update_cb<1>().set("huc6272", FUNC(huc6272_device::adpcm_update_1));
+ huc6230.cdda_cb().set("huc6272", FUNC(huc6272_device::cdda_update));
huc6230.add_route(0, "lspeaker", 1.0);
huc6230.add_route(1, "rspeaker", 1.0);
MACHINE_CONFIG_END