mirror of
https://github.com/holub/mame
synced 2025-07-06 02:18:09 +03:00
-spg2xx_audio: Hooked up channel FIQ. [Ryan Holtz]
This commit is contained in:
parent
6a63b36249
commit
dd6b5e332b
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user