From 4fb8e776b35237dd918b89fdd7d525a1444c6f15 Mon Sep 17 00:00:00 2001 From: David Haywood Date: Wed, 18 Oct 2017 15:38:46 +0100 Subject: [PATCH] Gamate sound is 100% AY8910 compatible according to Kevtris and Peter Wilhelmsen, us the AY8910 core. --- scripts/target/mame/mess.lua | 2 - src/mame/audio/gamate.cpp | 253 ----------------------------------- src/mame/audio/gamate.h | 96 ------------- src/mame/drivers/gamate.cpp | 33 +++-- 4 files changed, 24 insertions(+), 360 deletions(-) delete mode 100644 src/mame/audio/gamate.cpp delete mode 100644 src/mame/audio/gamate.h diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index d0026297337..fc525cd6f30 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -3467,8 +3467,6 @@ files { MAME_DIR .. "src/mame/drivers/fk1.cpp", MAME_DIR .. "src/mame/drivers/ft68m.cpp", MAME_DIR .. "src/mame/drivers/gamate.cpp", - MAME_DIR .. "src/mame/audio/gamate.cpp", - MAME_DIR .. "src/mame/audio/gamate.h", MAME_DIR .. "src/mame/drivers/gameking.cpp", MAME_DIR .. "src/mame/drivers/gimix.cpp", MAME_DIR .. "src/mame/drivers/goupil.cpp", diff --git a/src/mame/audio/gamate.cpp b/src/mame/audio/gamate.cpp deleted file mode 100644 index 8af8c1ce166..00000000000 --- a/src/mame/audio/gamate.cpp +++ /dev/null @@ -1,253 +0,0 @@ -// license:GPL-2.0+ -// copyright-holders:Peter Trauner -/*************************************************************************** - gamate sound hardware - - PeT mess@utanet.at 2015 -***************************************************************************/ - -#include "emu.h" -#include "audio/gamate.h" - - -enum { ClockDelay=32 }; - -// device type definition -DEFINE_DEVICE_TYPE(GAMATE_SND, gamate_sound_device, "gamate_sound", "Gamate Audio Custom") - -const int gamate_sound_device::DAConverter[]={ 0, 3, 7, 13, 23, 41, 75, 137, 249, 453, 825, 1499, 2726, 4956, 9011, 16383 }; // (*.55) on the real below index 8 bareless measureable -const uint8_t Mask[]={ 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0x1f, 0x3f, 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0xf }; -const int EnvelopeVolumes[]={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - -//------------------------------------------------- -// gamate_sound_device - constructor -//------------------------------------------------- - -gamate_sound_device::gamate_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, GAMATE_SND, tag, owner, clock) - , device_sound_interface(mconfig, *this) - , m_mixer_channel(nullptr) -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void gamate_sound_device::device_start() -{ - // bind callbacks -// m_irq_cb.bind_relative_to(*owner()); - - memset(m_channels, 0, sizeof(m_channels)); - memset(reg, 0, sizeof(reg)); - - m_mixer_channel = stream_alloc(0, 2, machine().sample_rate()); -} - - -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- - -void gamate_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) -{ - stream_sample_t *left=outputs[0], *right=outputs[1]; - int i, j; - Tone *channel; - - for (i = 0; i < samples; i++, left++, right++) - { - noise.pos += noise.step; - while (noise.pos >= 1.0) - { - // guess (white noise register taken from supervision) - noise.level = noise.state & 0x40 ? 1 : 0; - bool b1 = (noise.state & 0x40) != 0, b2 = (noise.state & 0x20) != 0; - noise.state=(noise.state<<1)+(b1!=b2?1:0); - noise.pos -= 1; - } - - envelope.pos += envelope.step; - while (envelope.pos >= 1.0) { - envelope.pos -= 1; - envelope.index++; - switch (envelope.control) - { - case 0: case 1: case 2: case 3: - case 4: case 5: case 6: case 7: - case 8: case 9: case 0xb: - case 0xd: case 0xf: - if (envelope.index>=ARRAY_LENGTH(EnvelopeVolumes)/2) - { - envelope.index=0; - envelope.first=false; - } - break; - default: - if (envelope.index>=ARRAY_LENGTH(EnvelopeVolumes)) - { - envelope.index=0; - envelope.first=false; - } - break; - } - } - - *left = 0; - *right = 0; - for (channel=m_channels, j=0; jsize != 0) - { - channel->level= channel->pos <= channel->size / 2; - bool l= channel->full_cycle? true: channel->level; - if (!channel->tone) - l= l && noise.level; - int volume=0; - if (l) - { - if (channel->envelope_on) - { - switch (envelope.control) - { - case 0: case 1: case 2: case 3: - case 0x9: // one time falling, low - if (envelope.first && channel->level) - volume=0xf-EnvelopeVolumes[envelope.index]; - break; - case 4: case 5: case 6: case 7: - case 0xf: // one time rising, low - if (envelope.first && channel->level) - volume=EnvelopeVolumes[envelope.index]; - break; - case 8: // falling - if (channel->level) - volume=0xf-EnvelopeVolumes[envelope.index]; - break; - case 0xa: // rising, falling - if (channel->level) - volume=0xf-EnvelopeVolumes[envelope.index]; // cube up - break; - case 0xb: // one time falling, high - if (channel->level) - volume=envelope.first ? 0xf-EnvelopeVolumes[envelope.index] : 0xf; - break; - case 0xc: // rising, low - if (channel->level) - volume=envelope.indexlevel) - volume=envelope.first ? EnvelopeVolumes[envelope.index] : 0xf; - break; - case 0xe: // falling, rising - if (channel->level) - volume=0xf-EnvelopeVolumes[envelope.index]; - break; - } - } - else - { - volume=channel->volume; - } - } - if (j == Right) - *right += Value2Volume(volume); - else - if (j==Left) - *left += Value2Volume(volume); - else - { - *right += Value2Volume(volume); - *left += Value2Volume(volume); - } - channel->pos++; - if (channel->pos >= channel->size) - channel->pos = 0; - } - } - } -} - -WRITE8_MEMBER( gamate_sound_device::device_w ) -{ - uint16_t size; - - m_mixer_channel->update(); - reg[offset] = data; - int chan=-1; - - switch (offset&0xf) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chan=offset/2; - size = reg[chan*2] | ((reg[chan*2+1] & 0xf) << 8); - if (size) - { - m_channels[chan].size= (int) (machine().sample_rate() * size*ClockDelay / m_clock); - } - else - { - m_channels[chan].size = 0; - } - m_channels[chan].pos = 0; - break; - case 6: - size=data&0x1f; - if (size==0) - size=1; - noise.step= m_clock / (1.0*ClockDelay*machine().sample_rate()*size); - break; - case 7: - m_channels[Right].full_cycle=data&1; - m_channels[Right].tone=data&8; - m_channels[Left].full_cycle=data&2; - m_channels[Left].tone=data&0x10; - m_channels[Both].full_cycle=data&4; - m_channels[Both].tone=data&0x20; - noise.state=1; - noise.pos=0.0; - noise.level=false; - break; - case 8: - case 9: - case 0xa: - chan=offset-8; - m_channels[chan].envelope_on = data & 0x10; // buggy aussetzer cube up - m_channels[chan].volume = data & 0xf; - break; - case 0xb: case 0xc: - size = reg[0xb] | ((reg[0xc]) << 8); - if (size==0) - size=1; - envelope.step= m_clock / (1.0*ClockDelay*machine().sample_rate()*size); - break; - case 0xd: - envelope.control=data&0xf; - envelope.pos=0; - envelope.index=0; - envelope.first=true; - break; - - } - envelope.pos=0; // guess - envelope.index=0; - envelope.first=true; -} - -READ8_MEMBER( gamate_sound_device::device_r ) -{ - uint8_t data=0; - if ((offset&0xf) gamate_sound_device - -class gamate_sound_device : public device_t, public device_sound_interface -{ -public: - gamate_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - DECLARE_WRITE8_MEMBER( device_w ); - DECLARE_READ8_MEMBER( device_r ); - -protected: - // device-level overrides - virtual void device_start() override; - - // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; - -private: - - static const int DAConverter[]; - static int Value2Volume(int volume) { return DAConverter[volume]*1; } - - sound_stream *m_mixer_channel; - struct Tone - { - Tone() : - envelope_on(false), - level(false), - tone(false), full_cycle(false), - volume(0), - pos(0), - size(0) - { - } - - bool envelope_on, level; - bool tone/*else noise*/, full_cycle/* else square signal/pulse */; - int volume; - int pos, size; - }; - - enum - { - Right, - Left, - Both - }; - - Tone m_channels[3]; - - struct Noise - { - Noise(): - state(1), - level(false), - step(0.0), - pos(0.0) - {} - - int state; - bool level; - double step, pos; - } noise; - - struct Envelope - { - Envelope(): - control(0), - index(0), - first(false) - {} - - int control; - int index; - bool first; - double step, pos; - } envelope; - - uint8_t reg[14]; -}; - -DECLARE_DEVICE_TYPE(GAMATE_SND, gamate_sound_device) - -#endif // MAME_AUDIO_GAMATE_H diff --git a/src/mame/drivers/gamate.cpp b/src/mame/drivers/gamate.cpp index 132cdc1e4d0..f80115e65fc 100644 --- a/src/mame/drivers/gamate.cpp +++ b/src/mame/drivers/gamate.cpp @@ -14,8 +14,7 @@ ******************************************************************************/ #include "emu.h" -#include "audio/gamate.h" - +#include "sound/ay8910.h" #include "bus/generic/carts.h" #include "bus/generic/slot.h" #include "cpu/m6502/m6502.h" @@ -30,7 +29,7 @@ public: gamate_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") - , m_sound(*this, "custom") + , m_ay(*this, "ay8910") , m_cart(*this, "cartslot") , m_io_joy(*this, "JOY") , m_palette(*this, "palette") @@ -50,6 +49,8 @@ public: DECLARE_READ8_MEMBER(gamate_video_r); DECLARE_READ8_MEMBER(gamate_nmi_r); DECLARE_WRITE8_MEMBER(gamate_video_w); + DECLARE_WRITE8_MEMBER(sound_w); + DECLARE_READ8_MEMBER(sound_r); DECLARE_DRIVER_INIT(gamate); uint32_t screen_update_gamate(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); INTERRUPT_GEN_MEMBER(gamate_interrupt); @@ -83,7 +84,7 @@ private: } card_protection; required_device m_maincpu; - required_device m_sound; + required_device m_ay; required_device m_cart; required_ioport m_io_joy; required_device m_palette; @@ -229,9 +230,21 @@ READ8_MEMBER( gamate_state::gamate_nmi_r ) return data; } +READ8_MEMBER(gamate_state::sound_r) +{ + m_ay->address_w(space, 0, offset); + return m_ay->data_r(space, 0); +} + +WRITE8_MEMBER(gamate_state::sound_w) +{ + m_ay->address_w(space, 0, offset); + m_ay->data_w(space, 0, data & 0xff); +} + static ADDRESS_MAP_START( gamate_mem, AS_PROGRAM, 8, gamate_state ) AM_RANGE(0x0000, 0x03ff) AM_RAM - AM_RANGE(0x4000, 0x400d) AM_DEVREADWRITE("custom", gamate_sound_device, device_r, device_w) + AM_RANGE(0x4000, 0x400f) AM_READWRITE(sound_r,sound_w) AM_RANGE(0x4400, 0x4400) AM_READ_PORT("JOY") AM_RANGE(0x4800, 0x4800) AM_READ(gamate_nmi_r) AM_RANGE(0x5000, 0x5007) AM_READWRITE(gamate_video_r, gamate_video_w) @@ -394,10 +407,12 @@ static MACHINE_CONFIG_START( gamate ) MCFG_DEFAULT_LAYOUT(layout_lcd) /* sound hardware */ - MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") - MCFG_SOUND_ADD("custom", GAMATE_SND, 4433000/2) - MCFG_SOUND_ROUTE(0, "lspeaker", 0.50) - MCFG_SOUND_ROUTE(1, "rspeaker", 0.50) + MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") // Stereo headphone output + MCFG_SOUND_ADD("ay8910", AY8910, 4433000 / 2) // AY compatible, no actual AY chip present + MCFG_SOUND_ROUTE(0, "lspeaker", 0.5) + MCFG_SOUND_ROUTE(1, "rspeaker", 0.5) + MCFG_SOUND_ROUTE(2, "lspeaker", 0.25) + MCFG_SOUND_ROUTE(2, "rspeaker", 0.25) MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_linear_slot, "gamate_cart") MCFG_SOFTWARE_LIST_ADD("cart_list","gamate")