summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/swp30.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/swp30.cpp')
-rw-r--r--src/devices/sound/swp30.cpp33
1 files changed, 20 insertions, 13 deletions
diff --git a/src/devices/sound/swp30.cpp b/src/devices/sound/swp30.cpp
index db37c8bff68..d135a77f16c 100644
--- a/src/devices/sound/swp30.cpp
+++ b/src/devices/sound/swp30.cpp
@@ -437,6 +437,8 @@ const std::array<u32, 4> swp30_device::lfo_shape_centered_tri = { 0x00000000, 0x
const std::array<u32, 4> swp30_device::lfo_shape_offset_saw = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; // __////__
const std::array<u32, 4> swp30_device::lfo_shape_offset_tri = { 0x00000000, 0x00000000, 0x000fffff, 0x000fffff }; // __/\/\__
+const std::array<u8, 4> swp30_device::dpcm_offset = { 7, 6, 4, 0 };
+
swp30_device::swp30_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: cpu_device(mconfig, SWP30, tag, owner, clock),
device_sound_interface(mconfig, *this),
@@ -478,7 +480,7 @@ void swp30_device::device_start()
// Delta-packed samples decompression.
for(int i=0; i<128; i++) {
- s16 base = ((i & 0x1f) << (5+(i >> 5))) + (((1 << (i >> 5))-1) << 10);
+ s16 base = ((i & 0x1f) << (3+(i >> 5))) + (((1 << (i >> 5))-1) << 8);
m_dpcm[i | 0x80] = - base;
m_dpcm[i] = + base;
}
@@ -511,6 +513,7 @@ void swp30_device::device_start()
save_item(NAME(m_dpcm_current));
save_item(NAME(m_dpcm_next));
save_item(NAME(m_dpcm_address));
+ save_item(NAME(m_dpcm_sum));
save_item(NAME(m_sample_history));
@@ -568,6 +571,7 @@ void swp30_device::device_reset()
std::fill(m_dpcm_current.begin(), m_dpcm_current.end(), false);
std::fill(m_dpcm_next.begin(), m_dpcm_next.end(), false);
std::fill(m_dpcm_address.begin(), m_dpcm_address.end(), false);
+ std::fill(m_dpcm_sum.begin(), m_dpcm_sum.end(), 0);
std::fill(m_meg_program.begin(), m_meg_program.end(), 0);
std::fill(m_meg_const.begin(), m_meg_const.end(), 0);
@@ -731,11 +735,12 @@ void swp30_device::keyon_w(u16)
if(m_sample_end[chan] & 0x80000000)
dt = -dt;
m_dpcm_address[chan] = ((m_sample_address[chan] & 0xffffff) << 2) - dt;
+ m_dpcm_sum[chan] = 0;
m_lfo_phase[chan] = 0;
if(1)
- logerror("[%08d] keyon %02x %08x %08x %08x vol %04x env %04x %04x %04x\n", scount, chan, m_sample_start[chan], m_sample_end[chan], m_sample_address[chan], m_release_glo[chan], m_attack[chan], m_decay1[chan], m_decay2[chan]);
+ logerror("[%08d] keyon %02x %08x %08x %08x vol %04x env %04x %04x %04x pitch %04x pmod %04x\n", scount, chan, m_sample_start[chan], m_sample_end[chan], m_sample_address[chan], m_release_glo[chan], m_attack[chan], m_decay1[chan], m_decay2[chan], m_pitch[chan], m_lfo_step_pmod[chan]);
}
}
m_keyon_mask = 0;
@@ -1228,11 +1233,6 @@ uint32_t swp30_device::execute_max_cycles() const noexcept
return 1;
}
-uint32_t swp30_device::execute_input_lines() const noexcept
-{
- return 0;
-}
-
void swp30_device::meg_prg_map(address_map &map)
{
@@ -1285,10 +1285,10 @@ void swp30_device::state_string_export(const device_state_entry &entry, std::str
{
}
-void swp30_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
+void swp30_device::sound_stream_update(sound_stream &stream)
{
- outputs[0].put_int_clamp(0, m_meg_output[0], 32768);
- outputs[1].put_int_clamp(0, m_meg_output[1], 32768);
+ stream.put_int_clamp(0, 0, m_meg_output[0], 32768);
+ stream.put_int_clamp(1, 0, m_meg_output[1], 32768);
}
void swp30_device::change_mode_attack_decay1(int chan)
@@ -1317,6 +1317,7 @@ void swp30_device::execute_run()
{
while(m_icount >= 0) {
if(m_meg_pc == 0) {
+ scount++;
if(0) {
static std::array<mixer_slot, 0x80> mixer;
if(memcmp(mixer.data(), m_mixer.data(), sizeof(mixer))) {
@@ -1475,12 +1476,15 @@ void swp30_device::execute_run()
}
case 3: { // 8-bits delta-pcm
+ u8 offset = dpcm_offset[(m_sample_address[chan] >> 25) & 3];
+ u8 scale = (m_sample_address[chan] >> 27) & 7;
offs_t adr = m_dpcm_address[chan];
if(m_sample_end[chan] & 0x80000000) {
u32 target_address = (base_address << 2) + spos - 1;
while(adr >= target_address) {
m_dpcm_current[chan] = m_dpcm_next[chan];
- s32 sample = m_dpcm_next[chan] + m_dpcm[(m_rom_cache.read_dword(adr >> 2) >> (8*(adr & 3))) & 0xff];
+ m_dpcm_sum[chan] += m_dpcm[(m_rom_cache.read_dword(adr >> 2) >> (8*(adr & 3))) & 0xff] - offset;
+ s32 sample = (m_dpcm_sum[chan] << scale) >> 3;
adr --;
if(sample < -0x8000)
sample = -0x8000;
@@ -1492,7 +1496,9 @@ void swp30_device::execute_run()
u32 target_address = (base_address << 2) + spos + 1;
while(adr <= target_address) {
m_dpcm_current[chan] = m_dpcm_next[chan];
- s32 sample = m_dpcm_next[chan] + m_dpcm[(m_rom_cache.read_dword(adr >> 2) >> (8*(adr & 3))) & 0xff];
+ m_dpcm_sum[chan] += m_dpcm[(m_rom_cache.read_dword(adr >> 2) >> (8*(adr & 3))) & 0xff] - offset;
+ s32 sample = (m_dpcm_sum[chan] << scale) >> 3;
+ // logerror("## + sample %08x %02x %d\n", adr, (m_rom_cache.read_dword(adr >> 2) >> (8*(adr & 3))) & 0xff, sample);
adr ++;
if(sample < -0x8000)
sample = -0x8000;
@@ -1543,12 +1549,13 @@ void swp30_device::execute_run()
else {
s32 prev = m_sample_pos[chan];
do
- m_sample_pos[chan] = m_sample_pos[chan] - ((m_sample_end[chan] & 0xffffff) << 8) + ((m_sample_address[chan] >> 22) & 0xfc);
+ m_sample_pos[chan] -= (m_sample_end[chan] & 0xffffff) << 8;
while((m_sample_pos[chan] >> 8) >= (m_sample_end[chan] & 0xffffff));
if(m_sample_end[chan] & 0x80000000)
m_dpcm_address[chan] -= (m_sample_pos[chan] >> 8) - (prev >> 8);
else
m_dpcm_address[chan] += (m_sample_pos[chan] >> 8) - (prev >> 8);
+ m_dpcm_sum[chan] = 0;
}
}