summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/k054539.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/k054539.cpp')
-rw-r--r--src/devices/sound/k054539.cpp71
1 files changed, 33 insertions, 38 deletions
diff --git a/src/devices/sound/k054539.cpp b/src/devices/sound/k054539.cpp
index 17dd9c97501..3bcadb703b7 100644
--- a/src/devices/sound/k054539.cpp
+++ b/src/devices/sound/k054539.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Olivier Galibert
/*********************************************************
Konami 054539 (TOP) PCM Sound Chip
@@ -21,17 +21,16 @@ DEFINE_DEVICE_TYPE(K054539, k054539_device, "k054539", "K054539 ADPCM")
k054539_device::k054539_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, K054539, tag, owner, clock)
, device_sound_interface(mconfig, *this)
- , device_rom_interface(mconfig, *this, 24)
+ , device_rom_interface(mconfig, *this)
, flags(0)
- , ram(nullptr)
, reverb_pos(0)
, cur_ptr(0)
- , cur_limit(0)
, rom_addr(0)
, stream(nullptr)
, m_timer(nullptr)
, m_timer_state(0)
, m_timer_handler(*this)
+ , m_apan_cb(*this)
{
}
@@ -104,22 +103,21 @@ void k054539_device::keyoff(int channel)
regs[0x22c] &= ~(1 << channel);
}
-void k054539_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
+void k054539_device::sound_stream_update(sound_stream &stream)
{
-#define VOL_CAP 1.80
+ static constexpr double VOL_CAP = 1.80;
static const int16_t dpcm[16] = {
- 0 * 0x100, 1 * 0x100, 4 * 0x100, 9 * 0x100, 16 * 0x100, 25 * 0x100, 36 * 0x100, 49 * 0x100,
- -64 * 0x100, -49 * 0x100, -36 * 0x100, -25 * 0x100, -16 * 0x100, -9 * 0x100, -4 * 0x100, -1 * 0x100
+ 0 * 0x100, 1 * 0x100, 2 * 0x100, 4 * 0x100, 8 * 0x100, 16 * 0x100, 32 * 0x100, 64 * 0x100,
+ 0 * 0x100, -64 * 0x100, -32 * 0x100, -16 * 0x100, -8 * 0x100, -4 * 0x100, -2 * 0x100, -1 * 0x100
};
-
- int16_t *rbase = (int16_t *)ram.get();
+ int16_t *rbase = (int16_t *)&ram[0];
if(!(regs[0x22f] & 1))
return;
- for(int sample = 0; sample != samples; sample++) {
+ for(int sample = 0; sample != stream.samples(); sample++) {
double lval, rval;
if(!(flags & DISABLE_REVERB))
lval = rval = rbase[reverb_pos];
@@ -128,7 +126,7 @@ void k054539_device::sound_stream_update(sound_stream &stream, stream_sample_t *
rbase[reverb_pos] = 0;
for(int ch=0; ch<8; ch++)
- if(regs[0x22c] & (1<<ch)) {
+ if(BIT(regs[0x22c], ch)) {
unsigned char *base1 = regs + 0x20*ch;
unsigned char *base2 = regs + 0x200 + 0x2*ch;
channel *chan = channels + ch;
@@ -297,13 +295,13 @@ void k054539_device::sound_stream_update(sound_stream &stream, stream_sample_t *
}
}
reverb_pos = (reverb_pos + 1) & 0x1fff;
- outputs[0][sample] = int16_t(lval);
- outputs[1][sample] = int16_t(rval);
+ stream.put_int(0, sample, lval, 32768);
+ stream.put_int(1, sample, rval, 32768);
}
}
-void k054539_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+TIMER_CALLBACK_MEMBER(k054539_device::call_timer_handler)
{
if (regs[0x22f] & 0x20)
m_timer_handler(m_timer_state ^= 1);
@@ -315,10 +313,11 @@ void k054539_device::init_chip()
memset(posreg_latch, 0, sizeof(posreg_latch)); //*
flags |= UPDATE_AT_KEYON; //* make it default until proven otherwise
- ram = std::make_unique<uint8_t[]>(0x4000);
+ ram = std::make_unique<uint8_t []>(0x8000);
+
reverb_pos = 0;
cur_ptr = 0;
- memset(ram.get(), 0, 0x4000);
+ memset(&ram[0], 0, 0x8000);
stream = stream_alloc(0, 2, clock() / 384);
@@ -329,10 +328,9 @@ void k054539_device::init_chip()
save_item(NAME(flags));
save_item(NAME(regs));
- save_pointer(NAME(ram), 0x4000);
+ save_pointer(NAME(ram), 0x8000);
save_item(NAME(reverb_pos));
save_item(NAME(cur_ptr));
- save_item(NAME(cur_limit));
save_item(NAME(rom_addr));
save_item(NAME(m_timer_state));
@@ -429,16 +427,15 @@ void k054539_device::write(offs_t offset, u8 data)
break;
case 0x22d:
- if(rom_addr == 0x80)
- ram[cur_ptr] = data;
- cur_ptr++;
- if(cur_ptr == cur_limit)
- cur_ptr = 0;
+ if(rom_addr == 0x80) {
+ offs_t const addr = (cur_ptr & 0x3fff) | ((cur_ptr & 0x10000) >> 2);
+ ram[addr] = data;
+ }
+ cur_ptr = (cur_ptr + 1) & 0x1ffff;
break;
case 0x22e:
rom_addr = data;
- cur_limit = rom_addr == 0x80 ? 0x4000 : 0x20000;
cur_ptr = 0;
break;
@@ -473,7 +470,6 @@ void k054539_device::write(offs_t offset, u8 data)
void k054539_device::device_post_load()
{
- cur_limit = rom_addr == 0x80 ? 0x4000 : 0x20000;
}
u8 k054539_device::read(offs_t offset)
@@ -481,10 +477,10 @@ u8 k054539_device::read(offs_t offset)
switch(offset) {
case 0x22d:
if(regs[0x22f] & 0x10) {
- uint8_t res = (rom_addr == 0x80) ? ram[cur_ptr] : read_byte((0x20000*rom_addr)+cur_ptr);
- cur_ptr++;
- if(cur_ptr == cur_limit)
- cur_ptr = 0;
+ offs_t const addr = (cur_ptr & 0x3fff) | ((cur_ptr & 0x10000) >> 2);
+ uint8_t res = (rom_addr == 0x80) ? ram[addr] : read_byte((0x20000*rom_addr) + cur_ptr);
+ if(!machine().side_effects_disabled())
+ cur_ptr = (cur_ptr + 1) & 0x1ffff;
return res;
} else
return 0;
@@ -499,11 +495,10 @@ u8 k054539_device::read(offs_t offset)
void k054539_device::device_start()
{
- m_timer = timer_alloc(0);
+ m_timer = timer_alloc(FUNC(k054539_device::call_timer_handler), this);
- // resolve / bind callbacks
- m_timer_handler.resolve_safe();
- m_apan_cb.bind_relative_to(*owner());
+ // resolve delegates
+ m_apan_cb.resolve();
for (auto & elem : gain)
elem = 1.0;
@@ -544,17 +539,17 @@ void k054539_device::device_reset()
{
regs[0x22c] = 0;
regs[0x22f] = 0;
- memset(ram.get(), 0, 0x4000);
+ memset(&ram[0], 0, 0x8000);
m_timer->enable(false);
}
//-------------------------------------------------
-// rom_bank_updated - the rom bank has changed
+// rom_bank_pre_change - refresh the stream if the
+// ROM banking changes
//-------------------------------------------------
-void k054539_device::rom_bank_updated()
+void k054539_device::rom_bank_pre_change()
{
stream->update();
}
-