summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mooglyguy <therealmogminer@gmail.com>2020-02-07 20:01:27 +0100
committer mooglyguy <therealmogminer@gmail.com>2020-02-07 20:03:22 +0100
commitdd6b5e332b41a054c7aa22ff05c4d19c6b99e1dc (patch)
treec74e86dbb814e785da9bc5e93414b5cee78a95d7
parent6a63b36249c1448c01f2520613b175ee35a8b2ff (diff)
-spg2xx_audio: Hooked up channel FIQ. [Ryan Holtz]
-rw-r--r--src/devices/cpu/unsp/unsp_fxxx.cpp4
-rw-r--r--src/devices/machine/spg2xx.cpp7
-rw-r--r--src/devices/machine/spg2xx.h1
-rw-r--r--src/devices/machine/spg2xx_audio.cpp65
-rw-r--r--src/devices/machine/spg2xx_audio.h6
5 files changed, 70 insertions, 13 deletions
diff --git a/src/devices/cpu/unsp/unsp_fxxx.cpp b/src/devices/cpu/unsp/unsp_fxxx.cpp
index eed523c5568..66d195e7850 100644
--- a/src/devices/cpu/unsp/unsp_fxxx.cpp
+++ b/src/devices/cpu/unsp/unsp_fxxx.cpp
@@ -458,7 +458,7 @@ inline void unsp_device::execute_fxxx_110_group(uint16_t op)
// MULS 1 1 1 1* r r r 1* 1 0*s s s r r r (1* = sign bit, 1* = sign bit 0* = upper size bit)
// MULS ss with upper size bit not set
- unimplemented_opcode(op);
+ //unimplemented_opcode(op);
//return;
}
@@ -472,7 +472,7 @@ inline void unsp_device::execute_fxxx_111_group(uint16_t op)
// MULS 1 1 1 1* r r r 1* 1 1*s s s r r r (1* = sign bit, 1* = sign bit 1* = upper size bit)
// MULS ss with upper size bit set.
- unimplemented_opcode(op);
+ //unimplemented_opcode(op);
//return;
}
diff --git a/src/devices/machine/spg2xx.cpp b/src/devices/machine/spg2xx.cpp
index fe5d547c164..dc38e8b4a85 100644
--- a/src/devices/machine/spg2xx.cpp
+++ b/src/devices/machine/spg2xx.cpp
@@ -126,6 +126,11 @@ WRITE_LINE_MEMBER(spg2xx_device::audioirq_w)
set_state_unsynced(UNSP_IRQ4_LINE, state);
}
+WRITE_LINE_MEMBER(spg2xx_device::audiochirq_w)
+{
+ set_state_unsynced(UNSP_FIQ_LINE, state);
+}
+
WRITE_LINE_MEMBER(spg2xx_device::extirq_w)
{
set_state_unsynced(UNSP_IRQ5_LINE, state);
@@ -176,6 +181,7 @@ void spg24x_device::device_add_mconfig(machine_config &config)
{
SPG2XX_AUDIO(config, m_spg_audio, DERIVED_CLOCK(1, 1));
m_spg_audio->write_irq_callback().set(FUNC(spg24x_device::audioirq_w));
+ m_spg_audio->channel_irq_callback().set(FUNC(spg24x_device::audiochirq_w));
m_spg_audio->space_read_callback().set(FUNC(spg24x_device::space_r));
m_spg_audio->add_route(0, *this, 1.0, AUTO_ALLOC_INPUT, 0);
@@ -196,6 +202,7 @@ void spg28x_device::device_add_mconfig(machine_config &config)
{
SPG2XX_AUDIO(config, m_spg_audio, DERIVED_CLOCK(1, 1));
m_spg_audio->write_irq_callback().set(FUNC(spg28x_device::audioirq_w));
+ m_spg_audio->channel_irq_callback().set(FUNC(spg28x_device::audiochirq_w));
m_spg_audio->space_read_callback().set(FUNC(spg28x_device::space_r));
m_spg_audio->add_route(0, *this, 1.0, AUTO_ALLOC_INPUT, 0);
diff --git a/src/devices/machine/spg2xx.h b/src/devices/machine/spg2xx.h
index 83664b935c6..4927d0d9294 100644
--- a/src/devices/machine/spg2xx.h
+++ b/src/devices/machine/spg2xx.h
@@ -81,6 +81,7 @@ protected:
DECLARE_WRITE8_MEMBER(fiq_vector_w);
DECLARE_WRITE_LINE_MEMBER(videoirq_w);
DECLARE_WRITE_LINE_MEMBER(audioirq_w);
+ DECLARE_WRITE_LINE_MEMBER(audiochirq_w);
DECLARE_WRITE_LINE_MEMBER(timerirq_w);
DECLARE_WRITE_LINE_MEMBER(uartirq_w);
DECLARE_WRITE_LINE_MEMBER(extirq_w);
diff --git a/src/devices/machine/spg2xx_audio.cpp b/src/devices/machine/spg2xx_audio.cpp
index 7865b13b675..d0e9ebb3766 100644
--- a/src/devices/machine/spg2xx_audio.cpp
+++ b/src/devices/machine/spg2xx_audio.cpp
@@ -10,7 +10,7 @@
or at least not per-channel)
SPG110 Beat interrupt frequency might be different too, seems to
- trigger an FIQ, but music is very slow in jak_spdmo
+ trigger an IRQ, but music is very slow in jak_spdmo
GCM394 has 32 channels, and potentially a different register layout
it looks close but might be different enough to split off
@@ -48,6 +48,7 @@ spg2xx_audio_device::spg2xx_audio_device(const machine_config &mconfig, device_t
, device_sound_interface(mconfig, *this)
, m_space_read_cb(*this)
, m_irq_cb(*this)
+ , m_ch_irq_cb(*this)
{
}
@@ -99,10 +100,14 @@ void spg2xx_audio_device::device_start()
{
save_item(NAME(m_adpcm[i].m_signal), i);
save_item(NAME(m_adpcm[i].m_step), i);
+
+ m_channel_irq[i] = timer_alloc(TIMER_IRQ + i);
+ m_channel_irq[i]->adjust(attotime::never);
}
m_space_read_cb.resolve_safe(0);
m_irq_cb.resolve();
+ m_ch_irq_cb.resolve();
}
void spg2xx_audio_device::device_reset()
@@ -128,11 +133,27 @@ void spg2xx_audio_device::device_reset()
m_audio_ctrl_regs[AUDIO_CHANNEL_ENV_MODE] = 0x3f;
m_audio_beat->adjust(attotime::from_ticks(4, 281250), 0, attotime::from_ticks(4, 281250));
+
+ for (int i = 0; i < 16; i++)
+ {
+ m_channel_irq[i]->adjust(attotime::never);
+ }
}
void spg2xx_audio_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
+ if (id >= TIMER_IRQ && id < (TIMER_IRQ + 16))
+ {
+ const uint32_t bit = id - TIMER_IRQ;
+ if (!BIT(m_audio_ctrl_regs[AUDIO_CHANNEL_FIQ_STATUS], bit))
+ {
+ m_audio_ctrl_regs[AUDIO_CHANNEL_FIQ_STATUS] |= (1 << (id - TIMER_IRQ));
+ m_ch_irq_cb(1);
+ }
+ return;
+ }
+
switch (id)
{
case TIMER_BEAT:
@@ -437,8 +458,17 @@ WRITE16_MEMBER(spg2xx_audio_device::audio_ctrl_w)
{
if (!(m_audio_ctrl_regs[AUDIO_CHANNEL_STATUS] & mask))
{
- LOGMASKED(LOG_SPU_WRITES, "Enabling channel %d\n", channel_bit);
+ LOGMASKED(LOG_SPU_WRITES, "Enabling channel %d, rate %f\n", channel_bit, m_channel_rate[channel_bit]);
m_audio_ctrl_regs[offset] |= mask;
+ if (BIT(m_audio_ctrl_regs[AUDIO_CHANNEL_FIQ_ENABLE], channel_bit))
+ {
+ m_channel_irq[channel_bit]->adjust(attotime::from_hz(m_channel_rate[channel_bit]), 0, attotime::from_hz(m_channel_rate[channel_bit]));
+ }
+ else
+ {
+ m_channel_irq[channel_bit]->adjust(attotime::never);
+ }
+
if (!(m_audio_ctrl_regs[AUDIO_CHANNEL_STOP] & mask))
{
LOGMASKED(LOG_SPU_WRITES, "Stop not set, starting playback on channel %d, mask %04x\n", channel_bit, mask);
@@ -476,7 +506,12 @@ WRITE16_MEMBER(spg2xx_audio_device::audio_ctrl_w)
case AUDIO_CHANNEL_FIQ_STATUS:
LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Channel FIQ Acknowledge: %04x\n", data);
+ //machine().debug_break();
m_audio_ctrl_regs[offset] &= ~(data & AUDIO_CHANNEL_FIQ_STATUS_MASK);
+ if (!m_audio_ctrl_regs[offset])
+ {
+ m_ch_irq_cb(0);
+ }
break;
case AUDIO_BEAT_BASE_COUNT:
@@ -882,22 +917,30 @@ void spg2xx_audio_device::sound_stream_update(sound_stream &stream, stream_sampl
const uint16_t mask = (1 << channel);
if (m_audio_ctrl_regs[AUDIO_ENV_RAMP_DOWN] & mask)
{
+ if (m_rampdown_frame[channel] > 0)
+ {
+ m_rampdown_frame[channel]--;
+ }
+
if (m_rampdown_frame[channel] == 0)
{
LOGMASKED(LOG_RAMPDOWN, "Ticking rampdown for channel %d\n", channel);
audio_rampdown_tick(channel);
}
- m_rampdown_frame[channel]--;
}
else if (!(m_audio_ctrl_regs[AUDIO_CHANNEL_ENV_MODE] & mask))
{
+ if (m_envclk_frame[channel] > 0)
+ {
+ m_envclk_frame[channel]--;
+ }
+
if (m_envclk_frame[channel] == 0)
{
LOGMASKED(LOG_ENVELOPES, "Ticking envelope for channel %d\n", channel);
audio_envelope_tick(channel);
m_envclk_frame[channel] = get_envclk_frame_count(channel);
}
- m_envclk_frame[channel]--;
}
}
}
@@ -922,12 +965,12 @@ void spg2xx_audio_device::sound_stream_update(sound_stream &stream, stream_sampl
inline void spg2xx_audio_device::stop_channel(const uint32_t channel)
{
- // TODO: IRQs
m_audio_ctrl_regs[AUDIO_CHANNEL_ENABLE] &= ~(1 << channel);
m_audio_ctrl_regs[AUDIO_CHANNEL_STATUS] &= ~(1 << channel);
m_audio_regs[(channel << 4) | AUDIO_MODE] &= ~AUDIO_ADPCM_MASK;
m_audio_ctrl_regs[AUDIO_CHANNEL_TONE_RELEASE] &= ~(1 << channel);
m_audio_ctrl_regs[AUDIO_ENV_RAMP_DOWN] &= ~(1 << channel);
+ m_channel_irq[channel]->adjust(attotime::never);
}
bool spg2xx_audio_device::advance_channel(const uint32_t channel)
@@ -1110,6 +1153,7 @@ void spg2xx_audio_device::audio_beat_tick()
m_audio_curr_beat_base_count = m_audio_ctrl_regs[AUDIO_BEAT_BASE_COUNT];
uint16_t beat_count = m_audio_ctrl_regs[AUDIO_BEAT_COUNT] & AUDIO_BEAT_COUNT_MASK;
+
if (beat_count > 0)
{
beat_count--;
@@ -1198,6 +1242,12 @@ bool spg2xx_audio_device::audio_envelope_tick(const uint32_t channel)
const uint16_t curr_edd = get_edd(channel);
LOGMASKED(LOG_ENVELOPES, "envelope %d tick, count is %04x, curr edd is %04x\n", channel, new_count, curr_edd);
bool edd_changed = false;
+ if (new_count > 0)
+ {
+ new_count--;
+ set_envelope_count(channel, new_count);
+ }
+
if (new_count == 0)
{
const uint16_t target = get_envelope_target(channel);
@@ -1276,11 +1326,6 @@ bool spg2xx_audio_device::audio_envelope_tick(const uint32_t channel)
edd_changed = true;
LOGMASKED(LOG_ENVELOPES, "Setting channel %d edd to %04x, register is %04x\n", channel, new_edd, m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA]);
}
- else
- {
- new_count--;
- set_envelope_count(channel, new_count);
- }
LOGMASKED(LOG_ENVELOPES, "envelope %d post-tick, count is now %04x, register is %04x\n", channel, new_count, m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA]);
return edd_changed;
}
diff --git a/src/devices/machine/spg2xx_audio.h b/src/devices/machine/spg2xx_audio.h
index 7154dccfad9..05c68282a14 100644
--- a/src/devices/machine/spg2xx_audio.h
+++ b/src/devices/machine/spg2xx_audio.h
@@ -22,6 +22,7 @@ public:
auto space_read_callback() { return m_space_read_cb.bind(); }
auto write_irq_callback() { return m_irq_cb.bind(); }
+ auto channel_irq_callback() { return m_ch_irq_cb.bind(); }
DECLARE_READ16_MEMBER(audio_r);
virtual DECLARE_WRITE16_MEMBER(audio_w);
@@ -322,6 +323,8 @@ protected:
};
static const device_timer_id TIMER_BEAT = 3;
+ static const device_timer_id TIMER_IRQ = 4;
+
void check_irqs(const uint16_t changed);
virtual void device_start() override;
@@ -354,6 +357,7 @@ protected:
uint16_t m_audio_curr_beat_base_count;
emu_timer *m_audio_beat;
+ emu_timer *m_channel_irq[16];
sound_stream *m_stream;
oki_adpcm_state m_adpcm[16];
@@ -364,7 +368,7 @@ protected:
private:
devcb_read16 m_space_read_cb;
devcb_write_line m_irq_cb;
-
+ devcb_write_line m_ch_irq_cb;
};
class spg110_audio_device : public spg2xx_audio_device