diff options
author | mooglyguy <therealmogminer@gmail.com> | 2020-02-07 20:01:27 +0100 |
---|---|---|
committer | mooglyguy <therealmogminer@gmail.com> | 2020-02-07 20:03:22 +0100 |
commit | dd6b5e332b41a054c7aa22ff05c4d19c6b99e1dc (patch) | |
tree | c74e86dbb814e785da9bc5e93414b5cee78a95d7 /src/devices/machine | |
parent | 6a63b36249c1448c01f2520613b175ee35a8b2ff (diff) |
-spg2xx_audio: Hooked up channel FIQ. [Ryan Holtz]
Diffstat (limited to 'src/devices/machine')
-rw-r--r-- | src/devices/machine/spg2xx.cpp | 7 | ||||
-rw-r--r-- | src/devices/machine/spg2xx.h | 1 | ||||
-rw-r--r-- | src/devices/machine/spg2xx_audio.cpp | 65 | ||||
-rw-r--r-- | src/devices/machine/spg2xx_audio.h | 6 |
4 files changed, 68 insertions, 11 deletions
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 |