summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/c352.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/c352.cpp')
-rw-r--r--src/devices/sound/c352.cpp173
1 files changed, 80 insertions, 93 deletions
diff --git a/src/devices/sound/c352.cpp b/src/devices/sound/c352.cpp
index 142c82349bb..dcbd58f3eb3 100644
--- a/src/devices/sound/c352.cpp
+++ b/src/devices/sound/c352.cpp
@@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont, superctr
/*
- c352.c - Namco C352 custom PCM chip emulation
+ c352.cpp - Namco C352 custom PCM chip emulation
v2.0
By R. Belmont
Rewritten and improved by superctr
@@ -27,7 +27,7 @@
#if C352_LOG_PCM
#include <map>
-static std::map<uint32_t, bool> s_found_pcm;
+static std::map<u32, bool> s_found_pcm;
#endif
// device type definition
@@ -41,19 +41,20 @@ DEFINE_DEVICE_TYPE(C352, c352_device, "c352", "Namco C352")
// c352_device - constructor
//-------------------------------------------------
-c352_device::c352_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+c352_device::c352_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, C352, tag, owner, clock)
, device_sound_interface(mconfig, *this)
- , device_rom_interface(mconfig, *this, 24)
+ , device_rom_interface(mconfig, *this)
, m_stream(nullptr)
{
}
//-------------------------------------------------
-// rom_bank_updated - the rom bank has changed
+// rom_bank_pre_change - refresh the stream if the
+// ROM banking changes
//-------------------------------------------------
-void c352_device::rom_bank_updated()
+void c352_device::rom_bank_pre_change()
{
m_stream->update();
}
@@ -69,14 +70,14 @@ void c352_device::fetch_sample(c352_voice_t& v)
}
else
{
- int8_t s = (int8_t)read_byte(v.pos);
+ s8 s = (s8)read_byte(v.pos);
if (v.flags & C352_FLG_MULAW)
v.sample = m_mulawtab[s & 0xff];
else
v.sample = s << 8;
- uint16_t pos = v.pos & 0xffff;
+ u16 pos = v.pos & 0xffff;
if ((v.flags & C352_FLG_LOOP) && v.flags & C352_FLG_REVERSE)
{
@@ -115,32 +116,32 @@ void c352_device::fetch_sample(c352_voice_t& v)
}
}
-void c352_device::ramp_volume(c352_voice_t &v, int ch, uint8_t val)
+void c352_device::ramp_volume(c352_voice_t &v, int ch, u8 val)
{
- int16_t vol_delta = v.curr_vol[ch] - val;
+ s16 vol_delta = v.curr_vol[ch] - val;
if (vol_delta != 0)
v.curr_vol[ch] += (vol_delta > 0) ? -1 : 1;
}
-void c352_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
+void c352_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
{
- stream_sample_t *buffer_fl = outputs[0];
- stream_sample_t *buffer_fr = outputs[1];
- stream_sample_t *buffer_rl = outputs[2];
- stream_sample_t *buffer_rr = outputs[3];
+ auto &buffer_fl = outputs[0];
+ auto &buffer_fr = outputs[1];
+ auto &buffer_rl = outputs[2];
+ auto &buffer_rr = outputs[3];
- for (int i = 0; i < samples; i++)
+ for (int i = 0; i < buffer_fl.samples(); i++)
{
- long out[4] = { 0, 0, 0, 0 };
+ int out[4] = { 0, 0, 0, 0 };
for (int j = 0; j < 32; j++)
{
c352_voice_t &v = m_c352_v[j];
- int16_t s = 0;
+ s16 s = 0;
if (v.flags & C352_FLG_BUSY)
{
- int32_t next_counter = v.counter + v.freq;
+ s32 next_counter = v.counter + v.freq;
if (next_counter & 0x10000)
{
@@ -173,32 +174,32 @@ void c352_device::sound_stream_update(sound_stream &stream, stream_sample_t **in
out[3] += (((v.flags & C352_FLG_PHASEFR) ? -s : s) * v.curr_vol[3]) >> 8;
}
- *buffer_fl++ = (int16_t)(out[0] >> 3);
- *buffer_fr++ = (int16_t)(out[1] >> 3);
- *buffer_rl++ = (int16_t)(out[2] >> 3);
- *buffer_rr++ = (int16_t)(out[3] >> 3);
+ buffer_fl.put_int(i, s16(out[0] >> 3), 32768);
+ buffer_fr.put_int(i, s16(out[1] >> 3), 32768);
+ buffer_rl.put_int(i, s16(out[2] >> 3), 32768);
+ buffer_rr.put_int(i, s16(out[3] >> 3), 32768);
}
}
-uint16_t c352_device::read_reg16(unsigned long address)
+u16 c352_device::read(offs_t offset)
{
m_stream->update();
const int reg_map[8] =
{
- offsetof(c352_voice_t, vol_f) / sizeof(uint16_t),
- offsetof(c352_voice_t, vol_r) / sizeof(uint16_t),
- offsetof(c352_voice_t, freq) / sizeof(uint16_t),
- offsetof(c352_voice_t, flags) / sizeof(uint16_t),
- offsetof(c352_voice_t, wave_bank) / sizeof(uint16_t),
- offsetof(c352_voice_t, wave_start) / sizeof(uint16_t),
- offsetof(c352_voice_t, wave_end) / sizeof(uint16_t),
- offsetof(c352_voice_t, wave_loop) / sizeof(uint16_t),
+ offsetof(c352_voice_t, vol_f) / sizeof(u16),
+ offsetof(c352_voice_t, vol_r) / sizeof(u16),
+ offsetof(c352_voice_t, freq) / sizeof(u16),
+ offsetof(c352_voice_t, flags) / sizeof(u16),
+ offsetof(c352_voice_t, wave_bank) / sizeof(u16),
+ offsetof(c352_voice_t, wave_start) / sizeof(u16),
+ offsetof(c352_voice_t, wave_end) / sizeof(u16),
+ offsetof(c352_voice_t, wave_loop) / sizeof(u16),
};
- if (address < 0x100)
- return *((uint16_t*)&m_c352_v[address / 8] + reg_map[address % 8]);
- else if (address == 0x200)
+ if (offset < 0x100)
+ return *((u16*)&m_c352_v[offset / 8] + reg_map[offset % 8]);
+ else if (offset == 0x200)
return m_control;
else
return 0;
@@ -206,33 +207,38 @@ uint16_t c352_device::read_reg16(unsigned long address)
return 0;
}
-void c352_device::write_reg16(unsigned long address, unsigned short val)
+void c352_device::write(offs_t offset, u16 data, u16 mem_mask)
{
m_stream->update();
const int reg_map[8] =
{
- offsetof(c352_voice_t, vol_f) / sizeof(uint16_t),
- offsetof(c352_voice_t, vol_r) / sizeof(uint16_t),
- offsetof(c352_voice_t, freq) / sizeof(uint16_t),
- offsetof(c352_voice_t, flags) / sizeof(uint16_t),
- offsetof(c352_voice_t, wave_bank) / sizeof(uint16_t),
- offsetof(c352_voice_t, wave_start) / sizeof(uint16_t),
- offsetof(c352_voice_t, wave_end) / sizeof(uint16_t),
- offsetof(c352_voice_t, wave_loop) / sizeof(uint16_t),
+ offsetof(c352_voice_t, vol_f) / sizeof(u16),
+ offsetof(c352_voice_t, vol_r) / sizeof(u16),
+ offsetof(c352_voice_t, freq) / sizeof(u16),
+ offsetof(c352_voice_t, flags) / sizeof(u16),
+ offsetof(c352_voice_t, wave_bank) / sizeof(u16),
+ offsetof(c352_voice_t, wave_start) / sizeof(u16),
+ offsetof(c352_voice_t, wave_end) / sizeof(u16),
+ offsetof(c352_voice_t, wave_loop) / sizeof(u16),
};
- if (address < 0x100)
+ if (offset < 0x100)
{
- *((uint16_t*)&m_c352_v[address / 8] + reg_map[address % 8]) = val;
+ u16 newval = read(offset);
+ COMBINE_DATA(&newval);
+ *((u16*)&m_c352_v[offset / 8] + reg_map[offset % 8]) = newval;
}
- else if (address == 0x200)
+ else if (offset == 0x200)
{
- m_control = val;
- logerror("C352 control register write: %04x\n",val);
+ COMBINE_DATA(&m_control);
+ logerror("C352 control register write: %04x & %04x\n", data, mem_mask);
}
- else if (address == 0x202) // execute keyons/keyoffs
+ else if (offset == 0x202) // execute keyons/keyoffs
{
+ if (mem_mask != 0xffff) // 16 bit only?
+ return;
+
for (int i = 0; i < 32; i++)
{
if (m_c352_v[i].flags & C352_FLG_KEYON)
@@ -252,7 +258,7 @@ void c352_device::write_reg16(unsigned long address, unsigned short val)
#if C352_LOG_PCM
if (!(m_c352_v[i].flags & C352_FLG_NOISE))
{
- std::map<uint32_t, bool>::iterator iter = s_found_pcm.find(m_c352_v[i].pos);
+ std::map<u32, bool>::iterator iter = s_found_pcm.find(m_c352_v[i].pos);
if (iter != s_found_pcm.end())
{
return;
@@ -266,27 +272,27 @@ void c352_device::write_reg16(unsigned long address, unsigned short val)
if (file != nullptr)
{
c352_voice_t &v = m_c352_v[i];
- uint32_t pos = v.pos;
- uint32_t flags = v.flags;
- uint32_t counter = v.counter;
- int16_t sample = 0;
+ u32 pos = v.pos;
+ u32 flags = v.flags;
+ u32 counter = v.counter;
+ s16 sample = 0;
while (pos != v.wave_end && !(flags & C352_FLG_KEYOFF))
{
- int32_t next_counter = counter + v.freq;
+ s32 next_counter = counter + v.freq;
if (next_counter & 0x10000)
{
counter = next_counter & 0xffff;
- int8_t s = (int8_t)read_byte(pos);
+ s8 s = (s8)read_byte(pos);
if (v.flags & C352_FLG_MULAW)
sample = m_mulawtab[s & 0xff];
else
sample = s << 8;
- uint16_t subpos = pos & 0xffff;
+ u16 subpos = pos & 0xffff;
if ((flags & C352_FLG_LOOP) && flags & C352_FLG_REVERSE)
{
@@ -353,14 +359,14 @@ void c352_device::device_clock_changed()
if (m_stream != nullptr)
m_stream->set_sample_rate(m_sample_rate_base);
else
- m_stream = machine().sound().stream_alloc(*this, 0, 4, m_sample_rate_base);
+ m_stream = stream_alloc(0, 4, m_sample_rate_base);
}
void c352_device::device_start()
{
m_sample_rate_base = clock() / m_divider;
- m_stream = machine().sound().stream_alloc(*this, 0, 4, m_sample_rate_base);
+ m_stream = stream_alloc(0, 4, m_sample_rate_base);
// generate mulaw table (Output similar to namco's VC emulator)
int j = 0;
@@ -382,22 +388,20 @@ void c352_device::device_start()
m_mulawtab[i + 128] = (~m_mulawtab[i]) & 0xffe0;
// register save state info
- for (int i = 0; i < 32; i++)
- {
- save_item(NAME(m_c352_v[i].pos), i);
- save_item(NAME(m_c352_v[i].counter), i);
- save_item(NAME(m_c352_v[i].sample), i);
- save_item(NAME(m_c352_v[i].last_sample), i);
- save_item(NAME(m_c352_v[i].vol_f), i);
- save_item(NAME(m_c352_v[i].vol_r), i);
- save_item(NAME(m_c352_v[i].curr_vol), i);
- save_item(NAME(m_c352_v[i].freq), i);
- save_item(NAME(m_c352_v[i].flags), i);
- save_item(NAME(m_c352_v[i].wave_bank), i);
- save_item(NAME(m_c352_v[i].wave_start), i);
- save_item(NAME(m_c352_v[i].wave_end), i);
- save_item(NAME(m_c352_v[i].wave_loop), i);
- }
+ save_item(STRUCT_MEMBER(m_c352_v, pos));
+ save_item(STRUCT_MEMBER(m_c352_v, counter));
+ save_item(STRUCT_MEMBER(m_c352_v, sample));
+ save_item(STRUCT_MEMBER(m_c352_v, last_sample));
+ save_item(STRUCT_MEMBER(m_c352_v, vol_f));
+ save_item(STRUCT_MEMBER(m_c352_v, vol_r));
+ save_item(STRUCT_MEMBER(m_c352_v, curr_vol));
+ save_item(STRUCT_MEMBER(m_c352_v, freq));
+ save_item(STRUCT_MEMBER(m_c352_v, flags));
+ save_item(STRUCT_MEMBER(m_c352_v, wave_bank));
+ save_item(STRUCT_MEMBER(m_c352_v, wave_start));
+ save_item(STRUCT_MEMBER(m_c352_v, wave_end));
+ save_item(STRUCT_MEMBER(m_c352_v, wave_loop));
+
save_item(NAME(m_random));
save_item(NAME(m_control));
}
@@ -411,20 +415,3 @@ void c352_device::device_reset()
m_random = 0x1234;
m_control = 0;
}
-
-READ16_MEMBER( c352_device::read )
-{
- return read_reg16(offset);
-}
-
-WRITE16_MEMBER( c352_device::write )
-{
- if (mem_mask == 0xffff)
- {
- write_reg16(offset, data);
- }
- else
- {
- logerror("C352: byte-wide write unsupported at this time!\n");
- }
-}