summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/scsp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/scsp.cpp')
-rw-r--r--src/devices/sound/scsp.cpp123
1 files changed, 49 insertions, 74 deletions
diff --git a/src/devices/sound/scsp.cpp b/src/devices/sound/scsp.cpp
index 2ee00c22880..e471d35a811 100644
--- a/src/devices/sound/scsp.cpp
+++ b/src/devices/sound/scsp.cpp
@@ -36,9 +36,6 @@
#include <algorithm>
-static constexpr s32 clip16(int x) { return std::min(32767, std::max(-32768, x)); }
-static constexpr s32 clip18(int x) { return std::min(131071, std::max(-131072, x)); }
-
#define SHIFT 12
#define LFO_SHIFT 8
#define FIX(v) ((u32) ((float) (1 << SHIFT) * (v)))
@@ -148,7 +145,7 @@ DEFINE_DEVICE_TYPE(SCSP, scsp_device, "scsp", "Yamaha YMF292-F SCSP")
scsp_device::scsp_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, SCSP, tag, owner, clock),
device_sound_interface(mconfig, *this),
- device_rom_interface(mconfig, *this, 20, ENDIANNESS_BIG, 16),
+ device_rom_interface(mconfig, *this),
m_irq_cb(*this),
m_main_irq_cb(*this),
m_BUFPTR(0),
@@ -165,15 +162,11 @@ scsp_device::scsp_device(const machine_config &mconfig, const char *tag, device_
m_timerC(nullptr),
m_mcieb(0),
m_mcipd(0),
- m_bufferl(nullptr),
- m_bufferr(nullptr),
- m_exts0(nullptr),
- m_exts1(nullptr),
- m_length(0),
m_RBUFDST(nullptr)
{
std::fill(std::begin(m_RINGBUF), std::end(m_RINGBUF), 0);
std::fill(std::begin(m_MidiStack), std::end(m_MidiStack), 0);
+ std::fill(std::begin(m_MidiOutStack), std::end(m_MidiOutStack), 0);
std::fill(std::begin(m_LPANTABLE), std::end(m_LPANTABLE), 0);
std::fill(std::begin(m_RPANTABLE), std::end(m_RPANTABLE), 0);
std::fill(std::begin(m_TimPris), std::end(m_TimPris), 0);
@@ -207,12 +200,8 @@ void scsp_device::device_start()
// init the emulation
init();
- // set up the IRQ callbacks
- m_irq_cb.resolve_safe();
- m_main_irq_cb.resolve_safe();
-
// Stereo output with EXTS0,1 Input (External digital audio output)
- m_stream = machine().sound().stream_alloc(*this, 2, 2, clock() / 512);
+ m_stream = stream_alloc(2, 2, clock() / 512);
for (int slot = 0; slot < 32; slot++)
{
@@ -255,6 +244,7 @@ void scsp_device::device_start()
save_item(NAME(m_IrqTimBC));
save_item(NAME(m_IrqMidi));
+ save_item(NAME(m_MidiOutStack));
save_item(NAME(m_MidiOutW));
save_item(NAME(m_MidiOutR));
save_item(NAME(m_MidiStack));
@@ -297,8 +287,8 @@ void scsp_device::device_post_load()
for (int slot = 0; slot < 32; slot++)
Compute_LFO(&m_Slots[slot]);
- m_stream->set_output_gain(0, MVOL() / 15.0);
- m_stream->set_output_gain(1, MVOL() / 15.0);
+ set_output_gain(0, MVOL() / 15.0);
+ set_output_gain(1, MVOL() / 15.0);
}
//-------------------------------------------------
@@ -311,7 +301,7 @@ void scsp_device::device_clock_changed()
m_stream->set_sample_rate(clock() / 512);
}
-void scsp_device::rom_bank_updated()
+void scsp_device::rom_bank_pre_change()
{
m_stream->update();
}
@@ -320,14 +310,9 @@ void scsp_device::rom_bank_updated()
// sound_stream_update - handle a stream update
//-------------------------------------------------
-void scsp_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
+void scsp_device::sound_stream_update(sound_stream &stream)
{
- m_exts0 = inputs[0];
- m_exts1 = inputs[1];
- m_bufferl = outputs[0];
- m_bufferr = outputs[1];
- m_length = samples;
- DoMasterSamples(samples);
+ DoMasterSamples(stream);
}
u8 scsp_device::DecodeSCI(u8 irq)
@@ -376,7 +361,6 @@ void scsp_device::CheckPendingIRQ()
if (en & 8)
{
m_irq_cb(m_IrqMidi, ASSERT_LINE);
- m_udata.data[0x20/2] &= ~8;
return;
}
@@ -449,13 +433,13 @@ TIMER_CALLBACK_MEMBER(scsp_device::timerC_cb)
int scsp_device::Get_AR(int base, int R)
{
int Rate = base + (R << 1);
- return m_ARTABLE[std::min(63, std::max(0, Rate))];
+ return m_ARTABLE[std::clamp(Rate, 0, 63)];
}
int scsp_device::Get_DR(int base, int R)
{
int Rate = base + (R << 1);
- return m_DRTABLE[std::min(63, std::max(0, Rate))];
+ return m_DRTABLE[std::clamp(Rate, 0, 63)];
}
void scsp_device::Compute_EG(SCSP_SLOT *slot)
@@ -592,9 +576,9 @@ void scsp_device::init()
m_MidiOutR = m_MidiOutW = 0;
m_DSP.space = &this->space();
- m_timerA = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(scsp_device::timerA_cb), this));
- m_timerB = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(scsp_device::timerB_cb), this));
- m_timerC = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(scsp_device::timerC_cb), this));
+ m_timerA = timer_alloc(FUNC(scsp_device::timerA_cb), this);
+ m_timerB = timer_alloc(FUNC(scsp_device::timerB_cb), this);
+ m_timerC = timer_alloc(FUNC(scsp_device::timerC_cb), this);
for (i = 0; i < 0x400; ++i)
{
@@ -738,8 +722,8 @@ void scsp_device::UpdateReg(int reg)
switch (reg & 0x3f)
{
case 0x0:
- m_stream->set_output_gain(0, MVOL() / 15.0);
- m_stream->set_output_gain(1, MVOL() / 15.0);
+ set_output_gain(0, MVOL() / 15.0);
+ set_output_gain(1, MVOL() / 15.0);
break;
case 0x2:
case 0x3:
@@ -750,7 +734,7 @@ void scsp_device::UpdateReg(int reg)
break;
case 0x6:
case 0x7:
- midi_in(m_udata.data[0x6/2] & 0xff);
+ midi_out_w(m_udata.data[0x6/2] & 0xff);
break;
case 8:
case 9:
@@ -776,7 +760,7 @@ void scsp_device::UpdateReg(int reg)
break;
case 0x18:
case 0x19:
- if (!m_irq_cb.isnull())
+ if (!m_irq_cb.isunset())
{
m_TimPris[0] = 1 << ((m_udata.data[0x18/2] >> 8) & 0x7);
m_TimCnt[0] = (m_udata.data[0x18/2] & 0xff) << 8;
@@ -793,7 +777,7 @@ void scsp_device::UpdateReg(int reg)
break;
case 0x1a:
case 0x1b:
- if (!m_irq_cb.isnull())
+ if (!m_irq_cb.isunset())
{
m_TimPris[1] = 1 << ((m_udata.data[0x1A/2] >> 8) & 0x7);
m_TimCnt[1] = (m_udata.data[0x1A/2] & 0xff) << 8;
@@ -810,7 +794,7 @@ void scsp_device::UpdateReg(int reg)
break;
case 0x1C:
case 0x1D:
- if (!m_irq_cb.isnull())
+ if (!m_irq_cb.isunset())
{
m_TimPris[2] = 1 << ((m_udata.data[0x1C/2] >> 8) & 0x7);
m_TimCnt[2] = (m_udata.data[0x1C/2] & 0xff) << 8;
@@ -827,7 +811,7 @@ void scsp_device::UpdateReg(int reg)
break;
case 0x1e: // SCIEB
case 0x1f:
- if (!m_irq_cb.isnull())
+ if (!m_irq_cb.isunset())
{
CheckPendingIRQ();
@@ -837,7 +821,7 @@ void scsp_device::UpdateReg(int reg)
break;
case 0x20: // SCIPD
case 0x21:
- if (!m_irq_cb.isnull())
+ if (!m_irq_cb.isunset())
{
if (m_udata.data[0x1e/2] & m_udata.data[0x20/2] & 0x20)
popmessage("SCSP SCIPD write %04x, contact MAMEdev",m_udata.data[0x20/2]);
@@ -846,7 +830,7 @@ void scsp_device::UpdateReg(int reg)
case 0x22: //SCIRE
case 0x23:
- if (!m_irq_cb.isnull())
+ if (!m_irq_cb.isunset())
{
m_udata.data[0x20/2] &= ~m_udata.data[0x22/2];
ResetInterrupts();
@@ -873,7 +857,7 @@ void scsp_device::UpdateReg(int reg)
case 0x27:
case 0x28:
case 0x29:
- if (!m_irq_cb.isnull())
+ if (!m_irq_cb.isunset())
{
m_IrqTimA = DecodeSCI(SCITMA);
m_IrqTimBC = DecodeSCI(SCITMB);
@@ -916,13 +900,17 @@ void scsp_device::UpdateRegR(int reg)
u16 v = m_udata.data[0x4/2];
v &= 0xff00;
v |= m_MidiStack[m_MidiR];
- m_irq_cb(m_IrqMidi, CLEAR_LINE); // cancel the IRQ
logerror("Read %x from SCSP MIDI\n", v);
if (m_MidiR != m_MidiW)
{
++m_MidiR;
m_MidiR &= 31;
}
+ if (m_MidiR == m_MidiW) // if the input FIFO is empty, clear the IRQ
+ {
+ m_irq_cb(m_IrqMidi, CLEAR_LINE);
+ m_udata.data[0x20 / 2] &= ~8;
+ }
m_udata.data[0x4/2] = v;
}
break;
@@ -1276,17 +1264,9 @@ inline s32 scsp_device::UpdateSlot(SCSP_SLOT *slot)
return sample;
}
-void scsp_device::DoMasterSamples(int nsamples)
+void scsp_device::DoMasterSamples(sound_stream &stream)
{
- stream_sample_t *bufr,*bufl;
- stream_sample_t *exts[2];
-
- bufr = m_bufferr;
- bufl = m_bufferl;
- exts[0] = m_exts0;
- exts[1] = m_exts1;
-
- for (int s = 0; s < nsamples; ++s)
+ for (int s = 0; s < stream.samples(); ++s)
{
s32 smpl = 0, smpr = 0;
@@ -1342,7 +1322,7 @@ void scsp_device::DoMasterSamples(int nsamples)
SCSP_SLOT *slot = m_Slots + i + 16; // 100217, 100237 EFSDL, EFPAN for EXTS0/1
if (EFSDL(slot))
{
- m_DSP.EXTS[i] = exts[i][s];
+ m_DSP.EXTS[i] = s32(stream.get(i, s) * 32768.0);
u16 Enc = ((EFPAN(slot)) << 0x8) | ((EFSDL(slot)) << 0xd);
smpl += (m_DSP.EXTS[i] * m_LPANTABLE[Enc]) >> SHIFT;
smpr += (m_DSP.EXTS[i] * m_RPANTABLE[Enc]) >> SHIFT;
@@ -1351,17 +1331,14 @@ void scsp_device::DoMasterSamples(int nsamples)
if (DAC18B())
{
- smpl = clip18(smpl);
- smpr = clip18(smpr);
+ stream.put_int_clamp(0, s, smpl, 131072);
+ stream.put_int_clamp(1, s, smpr, 131072);
}
else
{
- smpl = clip16(smpl >> 2);
- smpr = clip16(smpr >> 2);
+ stream.put_int_clamp(0, s, smpl >> 2, 32768);
+ stream.put_int_clamp(1, s, smpr >> 2, 32768);
}
-
- *bufl++ = smpl;
- *bufr++ = smpr;
}
}
@@ -1448,22 +1425,14 @@ void scsp_device::exec_dma()
}
}
-#ifdef UNUSED_FUNCTION
-int IRQCB(void *param)
-{
- CheckPendingIRQ(param);
- return -1;
-}
-#endif
-
-READ16_MEMBER(scsp_device::read)
+u16 scsp_device::read(offs_t offset)
{
m_stream->update();
return r16(offset * 2);
}
-WRITE16_MEMBER(scsp_device::write)
+void scsp_device::write(offs_t offset, u16 data, u16 mem_mask)
{
m_stream->update();
@@ -1482,15 +1451,21 @@ void scsp_device::midi_in(u8 data)
CheckPendingIRQ();
}
-READ16_MEMBER(scsp_device::midi_out_r)
+u16 scsp_device::midi_out_r()
{
- u8 val;
-
- val = m_MidiStack[m_MidiR++];
- m_MidiR &= 31;
+ u8 val = m_MidiOutStack[m_MidiOutR++];
+ m_MidiOutR &= 31;
return val;
}
+void scsp_device::midi_out_w(u8 data)
+{
+ m_MidiOutStack[m_MidiOutW++] = data;
+ m_MidiOutW &= 31;
+
+ //CheckPendingIRQ();
+}
+
//LFO handling
#define LFIX(v) ((u32) ((float) (1 << LFO_SHIFT) * (v)))