summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author ajrhacker <ajrhacker@users.noreply.github.com>2019-03-31 14:04:02 -0400
committer GitHub <noreply@github.com>2019-03-31 14:04:02 -0400
commita14285494f16ef6b4e305b69294821f3e881a519 (patch)
tree668d6ca1933ebb93cefdecce0f2f297c2276c85d
parent7d2a98b25b8966df437a1c881818ffd095aa3a9f (diff)
parent01476ca0721dea3420f41ca7d2f04feb9024a0a9 (diff)
Merge pull request #4836 from DavidHaywood/300319
basic audio for SPG110 titles
-rw-r--r--src/devices/machine/spg110.cpp60
-rw-r--r--src/devices/machine/spg110.h24
-rw-r--r--src/devices/machine/spg2xx_audio.cpp36
-rw-r--r--src/devices/machine/spg2xx_audio.h23
-rw-r--r--src/mame/drivers/spg110.cpp10
5 files changed, 91 insertions, 62 deletions
diff --git a/src/devices/machine/spg110.cpp b/src/devices/machine/spg110.cpp
index 060ae511f0c..81cc5e53c23 100644
--- a/src/devices/machine/spg110.cpp
+++ b/src/devices/machine/spg110.cpp
@@ -18,10 +18,12 @@ DEFINE_DEVICE_TYPE(SPG110, spg110_device, "spg110", "SPG110 System-on-a-Chip")
spg110_device::spg110_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
+ , device_mixer_interface(mconfig, *this, 2)
, m_cpu(*this, finder_base::DUMMY_TAG)
, m_screen(*this, finder_base::DUMMY_TAG)
, m_spg_io(*this, "spg_io")
, m_spg_video(*this, "spg_video")
+ , m_spg_audio(*this, "spgaudio")
, m_porta_out(*this)
, m_portb_out(*this)
, m_portc_out(*this)
@@ -63,6 +65,18 @@ void spg110_device::configure_spg_io(spg2xx_io_device* io)
// io->write_ffrq_tmr2_irq_callback().set(FUNC(spg110_device::ffreq2_w));
}
+READ16_MEMBER(spg110_device::space_r)
+{
+ address_space &cpuspace = m_cpu->space(AS_PROGRAM);
+ return cpuspace.read_word(offset);
+}
+
+WRITE_LINE_MEMBER(spg110_device::audioirq_w)
+{
+ m_cpu->set_state_unsynced(UNSP_FIQ_LINE, state);
+}
+
+
void spg110_device::device_add_mconfig(machine_config &config)
{
SPG24X_IO(config, m_spg_io, DERIVED_CLOCK(1, 1), m_cpu, m_screen);
@@ -70,22 +84,15 @@ void spg110_device::device_add_mconfig(machine_config &config)
SPG110_VIDEO(config, m_spg_video, DERIVED_CLOCK(1, 1), m_cpu, m_screen);
m_spg_video->write_video_irq_callback().set(FUNC(spg110_device::videoirq_w));
-}
-WRITE16_MEMBER(spg110_device::spg110_3100_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3101_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3102_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3104_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3105_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3106_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3107_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3108_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3109_w) { }
-WRITE16_MEMBER(spg110_device::spg110_310b_w) { }
-WRITE16_MEMBER(spg110_device::spg110_310c_w) { }
-WRITE16_MEMBER(spg110_device::spg110_310d_w) { }
-
-READ16_MEMBER(spg110_device::spg110_310f_r) { return 0x0000; }
+ SPG110_AUDIO(config, m_spg_audio, DERIVED_CLOCK(1, 1));
+ m_spg_audio->write_irq_callback().set(FUNC(spg110_device::audioirq_w));
+ m_spg_audio->space_read_callback().set(FUNC(spg110_device::space_r));
+
+ m_spg_audio->add_route(0, *this, 1.0, AUTO_ALLOC_INPUT, 0);
+ m_spg_audio->add_route(1, *this, 1.0, AUTO_ALLOC_INPUT, 1);
+
+}
void spg110_device::map(address_map &map)
{
@@ -139,27 +146,12 @@ void spg110_device::map(address_map &map)
map(0x002100, 0x0021ff).ram(); // jak_spdmo only
map(0x002200, 0x0022ff).ram(); // looks like per-pen brightness or similar? strange because palette isn't memory mapped here (maybe rowscroll?)
-#if 1 // sound registers? seems to be 8 long entries, only uses up to 0x7f? (register mapping seems similar to spg2xx, maybe with less channels?)
- map(0x003000, 0x00307f).ram();
- map(0x003080, 0x0030ff).ram();
+ /// sound registers? seems to be 8 long entries, only uses up to 0x7f? (register mapping seems similar to spg2xx, maybe with less channels?)
+ map(0x003000, 0x00307f).rw(m_spg_audio, FUNC(spg110_audio_device::audio_r), FUNC(spg110_audio_device::audio_w));
+ map(0x003080, 0x0030ff).ram(); // extra ram? doesn't seem to be phase, and there only appear to be 8 channels on SPG110
- map(0x003100, 0x003100).w(FUNC(spg110_device::spg110_3100_w));
- map(0x003101, 0x003101).w(FUNC(spg110_device::spg110_3101_w));
- map(0x003102, 0x003102).w(FUNC(spg110_device::spg110_3102_w));
+ map(0x003100, 0x00310f).rw(m_spg_audio, FUNC(spg110_audio_device::audio_ctrl_r), FUNC(spg2xx_audio_device::audio_ctrl_w));
- map(0x003104, 0x003104).w(FUNC(spg110_device::spg110_3104_w));
- map(0x003105, 0x003105).w(FUNC(spg110_device::spg110_3105_w));
- map(0x003106, 0x003106).w(FUNC(spg110_device::spg110_3106_w));
- map(0x003107, 0x003107).w(FUNC(spg110_device::spg110_3107_w));
- map(0x003108, 0x003108).w(FUNC(spg110_device::spg110_3108_w));
- map(0x003109, 0x003109).w(FUNC(spg110_device::spg110_3109_w));
-
- map(0x00310b, 0x00310b).w(FUNC(spg110_device::spg110_310b_w));
- map(0x00310c, 0x00310c).w(FUNC(spg110_device::spg110_310c_w));
- map(0x00310d, 0x00310d).w(FUNC(spg110_device::spg110_310d_w));
-
- map(0x00310f, 0x00310f).r(FUNC(spg110_device::spg110_310f_r));
-#endif
// 0032xx looks like it could be the same as 003d00 on spg2xx
map(0x003200, 0x00322f).rw(m_spg_io, FUNC(spg2xx_io_device::io_r), FUNC(spg2xx_io_device::io_w));
diff --git a/src/devices/machine/spg110.h b/src/devices/machine/spg110.h
index 91a715fc755..01019d538cf 100644
--- a/src/devices/machine/spg110.h
+++ b/src/devices/machine/spg110.h
@@ -11,8 +11,9 @@
#include "emupal.h"
#include "spg2xx_io.h"
#include "spg110_video.h"
+#include "spg2xx_audio.h"
-class spg110_device : public device_t
+class spg110_device : public device_t, public device_mixer_interface
{
public:
@@ -35,7 +36,7 @@ public:
auto porta_in() { return m_porta_in.bind(); }
auto portb_in() { return m_portb_in.bind(); }
auto portc_in() { return m_portc_in.bind(); }
-
+
template <size_t Line> auto adc_in() { return m_adc_in[Line].bind(); }
auto chip_select() { return m_chip_sel.bind(); }
@@ -56,23 +57,10 @@ private:
required_device<spg2xx_io_device> m_spg_io;
required_device<spg110_video_device> m_spg_video;
+ required_device<spg110_audio_device> m_spg_audio;
- DECLARE_WRITE16_MEMBER(spg110_3100_w);
-
- DECLARE_WRITE16_MEMBER(spg110_3101_w);
- DECLARE_WRITE16_MEMBER(spg110_3102_w);
- DECLARE_WRITE16_MEMBER(spg110_3104_w);
- DECLARE_WRITE16_MEMBER(spg110_3105_w);
- DECLARE_WRITE16_MEMBER(spg110_3106_w);
- DECLARE_WRITE16_MEMBER(spg110_3107_w);
- DECLARE_WRITE16_MEMBER(spg110_3108_w);
- DECLARE_WRITE16_MEMBER(spg110_3109_w);
-
- DECLARE_WRITE16_MEMBER(spg110_310b_w);
- DECLARE_WRITE16_MEMBER(spg110_310c_w);
- DECLARE_WRITE16_MEMBER(spg110_310d_w);
-
- DECLARE_READ16_MEMBER(spg110_310f_r);
+ DECLARE_READ16_MEMBER(space_r);
+ DECLARE_WRITE_LINE_MEMBER(audioirq_w);
devcb_write16 m_porta_out;
devcb_write16 m_portb_out;
diff --git a/src/devices/machine/spg2xx_audio.cpp b/src/devices/machine/spg2xx_audio.cpp
index a09eb907694..5c488c2f1eb 100644
--- a/src/devices/machine/spg2xx_audio.cpp
+++ b/src/devices/machine/spg2xx_audio.cpp
@@ -4,12 +4,21 @@
SunPlus SPG2xx-series SoC peripheral emulation (Audio)
+ This is also used for SPG110, although that should be limited to
+ just 8 channels and has some things shifted around (phase appears
+ to be in the regular register set instead, formats might be fixed
+ 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
+
**********************************************************************/
#include "emu.h"
#include "spg2xx_audio.h"
-DEFINE_DEVICE_TYPE(SPG2XX_AUDIO, spg2xx_audio_device, "spg2xx", "SPG2xx-series System-on-a-Chip Audio")
+DEFINE_DEVICE_TYPE(SPG2XX_AUDIO, spg2xx_audio_device, "spg2xx_audio", "SPG2xx-series System-on-a-Chip Audio")
+DEFINE_DEVICE_TYPE(SPG110_AUDIO, spg110_audio_device, "spg110_audio", "SPG110-series System-on-a-Chip Audio")
#define LOG_SPU_READS (1U << 0)
#define LOG_SPU_WRITES (1U << 1)
@@ -43,6 +52,12 @@ spg2xx_audio_device::spg2xx_audio_device(const machine_config &mconfig, const ch
{
}
+spg110_audio_device::spg110_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : spg2xx_audio_device(mconfig, SPG110_AUDIO, tag, owner, clock)
+{
+}
+
+
void spg2xx_audio_device::device_start()
{
@@ -1256,3 +1271,22 @@ bool spg2xx_audio_device::audio_envelope_tick(const uint32_t channel)
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;
}
+
+
+
+WRITE16_MEMBER(spg110_audio_device::audio_w)
+{
+ const uint16_t channel = (offset & 0x00f0) >> 4;
+
+ switch (offset & AUDIO_CHAN_OFFSET_MASK)
+ {
+ case 0x0e:
+ m_audio_regs[offset] = data;
+ m_channel_rate[channel] = ((double)get_phase(channel) * 140625.0 * 2.0) / (double)(1 << 19);
+ m_channel_rate_accum[channel] = 0.0;
+ LOGMASKED(LOG_CHANNEL_WRITES, "spg110_audio_device::audio_w: Channel %d: Phase: %04x (rate: %f)\n", channel, data, m_channel_rate[channel]);
+ return;
+ }
+
+ spg2xx_audio_device::audio_w(space,offset,data,mem_mask);
+}
diff --git a/src/devices/machine/spg2xx_audio.h b/src/devices/machine/spg2xx_audio.h
index 22f5108e405..88d21fb1ecf 100644
--- a/src/devices/machine/spg2xx_audio.h
+++ b/src/devices/machine/spg2xx_audio.h
@@ -24,7 +24,7 @@ public:
auto write_irq_callback() { return m_irq_cb.bind(); }
DECLARE_READ16_MEMBER(audio_r);
- DECLARE_WRITE16_MEMBER(audio_w);
+ virtual DECLARE_WRITE16_MEMBER(audio_w);
DECLARE_READ16_MEMBER(audio_ctrl_r);
DECLARE_WRITE16_MEMBER(audio_ctrl_w);
DECLARE_READ16_MEMBER(audio_phase_r);
@@ -52,8 +52,8 @@ protected:
uint16_t get_wave_addr_high(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_WADDR_HIGH_MASK; }
uint16_t get_loop_addr_high(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_LADDR_HIGH_MASK) >> AUDIO_LADDR_HIGH_SHIFT; }
uint16_t get_tone_mode(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_TONE_MODE_MASK) >> AUDIO_TONE_MODE_SHIFT; }
- uint16_t get_16bit_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_16M_MASK) ? 1 : 0; }
- uint16_t get_adpcm_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_ADPCM_MASK) ? 1 : 0; }
+ virtual uint16_t get_16bit_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_16M_MASK) ? 1 : 0; }
+ virtual uint16_t get_adpcm_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_ADPCM_MASK) ? 1 : 0; }
// Audio Pan getters
uint16_t get_volume(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_PAN_VOL] & AUDIO_VOLUME_MASK; }
@@ -103,7 +103,7 @@ protected:
uint16_t get_phase_time_step(const offs_t channel) const { return (m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_CTRL] & AUDIO_PHASE_TIME_STEP_MASK) >> AUDIO_PHASE_TIME_STEP_SHIFT; }
// Audio combined getters
- uint32_t get_phase(const offs_t channel) const { return ((uint32_t)get_phase_high(channel) << 16) | m_audio_phase_regs[(channel << 4) | AUDIO_PHASE]; }
+ virtual uint32_t get_phase(const offs_t channel) const { return ((uint32_t)get_phase_high(channel) << 16) | m_audio_phase_regs[(channel << 4) | AUDIO_PHASE]; }
uint32_t get_phase_accum(const offs_t channel) const { return ((uint32_t)get_phase_accum_high(channel) << 16) | m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_ACCUM]; }
uint32_t get_target_phase(const offs_t channel) const { return ((uint32_t)get_target_phase_high(channel) << 16) | m_audio_phase_regs[(channel << 4) | AUDIO_TARGET_PHASE]; }
@@ -367,6 +367,21 @@ private:
};
+class spg110_audio_device : public spg2xx_audio_device
+{
+public:
+ spg110_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual DECLARE_WRITE16_MEMBER(audio_w) override;
+
+ // these either come from somewhere else on spg110 or are hardcoded
+ virtual uint16_t get_16bit_bit(const offs_t channel) const override { return 1; }
+ virtual uint16_t get_adpcm_bit(const offs_t channel) const override { return 0; }
+
+ virtual uint32_t get_phase(const offs_t channel) const override { return m_audio_regs[(channel << 4) | 0xe]; }
+};
+
DECLARE_DEVICE_TYPE(SPG2XX_AUDIO, spg2xx_audio_device)
+DECLARE_DEVICE_TYPE(SPG110_AUDIO, spg110_audio_device)
#endif // MAME_MACHINE_SPG2XX_AUDIO_H
diff --git a/src/mame/drivers/spg110.cpp b/src/mame/drivers/spg110.cpp
index dd65883129c..8ac0de20dfa 100644
--- a/src/mame/drivers/spg110.cpp
+++ b/src/mame/drivers/spg110.cpp
@@ -346,17 +346,17 @@ void spg110_game_state::spg110_base(machine_config &config)
m_screen->set_screen_update("spg", FUNC(spg110_device::screen_update));
m_screen->screen_vblank().set(m_spg, FUNC(spg110_device::vblank));
- SPEAKER(config, "lspeaker").front_left();
- SPEAKER(config, "rspeaker").front_right();
-// m_spg->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
-// m_spg->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
-
SPG110(config, m_spg, XTAL(27'000'000), m_maincpu, m_screen);
m_spg->porta_in().set_ioport("PA");
m_spg->portb_in().set_ioport("PB");
m_spg->portc_in().set_ioport("PC");
m_spg->adc_in<0>().set_ioport("JOYX");
m_spg->adc_in<1>().set_ioport("JOYY");
+
+ SPEAKER(config, "lspeaker").front_left();
+ SPEAKER(config, "rspeaker").front_right();
+ m_spg->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
+ m_spg->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
}
ROM_START( jak_capb )