From 3ffd6b839facbf554ffd1a8f52853f6cea518178 Mon Sep 17 00:00:00 2001 From: Dirk Best Date: Sat, 17 Mar 2018 09:08:28 +0100 Subject: [PATCH] uPD934G: Preliminary emulation --- scripts/src/sound.lua | 12 +++ scripts/target/mame/arcade.lua | 1 + scripts/target/mame/mess.lua | 1 + src/devices/sound/upd934g.cpp | 161 +++++++++++++++++++++++++++++++++ src/devices/sound/upd934g.h | 70 ++++++++++++++ 5 files changed, 245 insertions(+) create mode 100644 src/devices/sound/upd934g.cpp create mode 100644 src/devices/sound/upd934g.h diff --git a/scripts/src/sound.lua b/scripts/src/sound.lua index 72b21469220..a67c71ed782 100644 --- a/scripts/src/sound.lua +++ b/scripts/src/sound.lua @@ -1459,3 +1459,15 @@ if (SOUNDS["LC7535"]~=null) then MAME_DIR .. "src/devices/sound/lc7535.h", } end + +--------------------------------------------------- +-- NEC uPD934G +--@src/devices/sound/upd934g.h,SOUNDS["UPD934G"] = true +--------------------------------------------------- + +if (SOUNDS["UPD934G"]~=null) then + files { + MAME_DIR .. "src/devices/sound/upd934g.cpp", + MAME_DIR .. "src/devices/sound/upd934g.h", + } +end diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 809ea30252e..6b7fa76d002 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -268,6 +268,7 @@ SOUNDS["TA7630"] = true SOUNDS["MM5837"] = true --SOUNDS["DAVE"] = true SOUNDS["LC7535"] = true +--SOUNDS["UPD934G"] = true -------------------------------------------------- -- specify available video cores diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 375c3bc9221..4f1eb635908 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -270,6 +270,7 @@ SOUNDS["MEA8000"] = true --SOUNDS["MM5837"] = true SOUNDS["DAVE"] = true --SOUNDS["LC7535"] = true +SOUNDS["UPD934G"] = true -------------------------------------------------- -- specify available video cores diff --git a/src/devices/sound/upd934g.cpp b/src/devices/sound/upd934g.cpp new file mode 100644 index 00000000000..090fb98d725 --- /dev/null +++ b/src/devices/sound/upd934g.cpp @@ -0,0 +1,161 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + NEC μPD934G + + Percussion Generator + + TODO: + - Play MUTED and ACCENTED + - T1 input + - 8 channels? + +***************************************************************************/ + +#include "emu.h" +#include "upd934g.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(UPD934G, upd934g_device, "upd934g", "NEC uPD934G") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// upd934g_device - constructor +//------------------------------------------------- + +upd934g_device::upd934g_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, UPD934G, tag, owner, clock), + device_sound_interface(mconfig, *this), + m_data_cb(*this), + m_stream(nullptr), + m_sample(0), + m_ready(false) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void upd934g_device::device_start() +{ + // create sound stream + m_stream = machine().sound().stream_alloc(*this, 0, 4, 20000); + + // resolve callbacks + m_data_cb.resolve_safe(0); + + // register for save states + save_pointer(NAME(m_addr), 16); + + for (unsigned i = 0; i < 4; i++) + { + save_item(NAME(m_channel[i].pos), i); + save_item(NAME(m_channel[i].playing), i); + save_item(NAME(m_channel[i].volume), i); + } + + save_item(NAME(m_sample)); + save_item(NAME(m_ready)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void upd934g_device::device_reset() +{ + m_ready = false; + + for (unsigned i = 0; i < 4; i++) + m_channel[i].playing = -1; +} + +//------------------------------------------------- +// sound_stream_update - handle update requests for +// our sound stream +//------------------------------------------------- + +void upd934g_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ + for (unsigned ch = 0; ch < 4; ch++) + { + std::fill(&outputs[ch][0], &outputs[ch][samples], 0); + + if (m_ready && m_channel[ch].playing != -1) + { + uint16_t end = m_addr[m_channel[ch].playing + 1] - 1; + + for (unsigned i = 0; i < samples; i++) + { + int8_t raw = static_cast(m_data_cb(m_channel[ch].pos)); + outputs[ch][i] = raw * (m_channel[ch].volume + 1) * 64; + + if (++m_channel[ch].pos >= end) + { + m_channel[ch].playing = -1; + break; + } + } + } + } +} + + +//************************************************************************** +// INTERFACE +//************************************************************************** + +WRITE8_MEMBER( upd934g_device::write ) +{ + switch (offset) + { + case 0: + // format of data written here is: + // 76------ command + // --5432-- sample number + // ------10 volume? + m_sample = (data >> 2) & 0x0f; + switch (data >> 6) + { + case 0: + logerror("CMD STORE ADDRESS sample %x\n", m_sample); + break; + case 1: + logerror("CMD PLAY sample %x (channel %d)\n", m_sample, m_sample >> 1); + if (m_sample < 8) + { + m_channel[m_sample >> 1].pos = m_addr[m_sample]; + m_channel[m_sample >> 1].playing = m_sample; + m_channel[m_sample >> 1].volume = data & 0x03; + } + break; + case 2: + logerror("CMD PLAY MUTED sample %x (channel %d)\n", m_sample, m_sample >> 1); + break; + case 3: + logerror("CMD PLAY ACCENTED sample %x (channel %d)\n", m_sample, m_sample >> 1); + break; + } + break; + case 1: + m_addr[m_sample] = (m_addr[m_sample] & 0xff00) | (data << 0); + break; + case 2: + m_addr[m_sample] = (m_addr[m_sample] & 0x00ff) | (data << 8); + logerror(" sample %x address = %04x\n", m_sample, m_addr[m_sample]); + break; + case 3: + m_ready = true; + break; + } +} diff --git a/src/devices/sound/upd934g.h b/src/devices/sound/upd934g.h new file mode 100644 index 00000000000..02224f2739d --- /dev/null +++ b/src/devices/sound/upd934g.h @@ -0,0 +1,70 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + NEC μPD934G + + Percussion Generator + +***************************************************************************/ + +#ifndef MAME_SOUND_UPD934G_H +#define MAME_SOUND_UPD934G_H + +#pragma once + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_UPD934G_DATA_CB(_devcb) \ + devcb = &downcast(*device).set_data_callback(DEVCB_##_devcb); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class upd934g_device : public device_t, public device_sound_interface +{ +public: + static constexpr feature_type imperfect_features() { return feature::SOUND; } + + // construction/destruction + upd934g_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // configuration + template devcb_base &set_data_callback(Object &&cb) { return m_data_cb.set_callback(std::forward(cb)); } + + DECLARE_WRITE8_MEMBER(write); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + +private: + devcb_read8 m_data_cb; + sound_stream *m_stream; + + uint16_t m_addr[16]; + + struct + { + uint16_t pos; + int playing; + int volume; + } + m_channel[4]; + + int m_sample; + bool m_ready; +}; + +// device type definition +DECLARE_DEVICE_TYPE(UPD934G, upd934g_device) + +#endif // MAME_SOUND_UPD934G_H