mirror of
https://github.com/holub/mame
synced 2025-04-18 22:49:58 +03:00
uPD934G: Preliminary emulation
This commit is contained in:
parent
61f1bf7477
commit
3ffd6b839f
@ -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
|
||||
|
@ -268,6 +268,7 @@ SOUNDS["TA7630"] = true
|
||||
SOUNDS["MM5837"] = true
|
||||
--SOUNDS["DAVE"] = true
|
||||
SOUNDS["LC7535"] = true
|
||||
--SOUNDS["UPD934G"] = true
|
||||
|
||||
--------------------------------------------------
|
||||
-- specify available video cores
|
||||
|
@ -270,6 +270,7 @@ SOUNDS["MEA8000"] = true
|
||||
--SOUNDS["MM5837"] = true
|
||||
SOUNDS["DAVE"] = true
|
||||
--SOUNDS["LC7535"] = true
|
||||
SOUNDS["UPD934G"] = true
|
||||
|
||||
--------------------------------------------------
|
||||
-- specify available video cores
|
||||
|
161
src/devices/sound/upd934g.cpp
Normal file
161
src/devices/sound/upd934g.cpp
Normal file
@ -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<int8_t>(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;
|
||||
}
|
||||
}
|
70
src/devices/sound/upd934g.h
Normal file
70
src/devices/sound/upd934g.h
Normal file
@ -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<upd934g_device &>(*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 <class Object> devcb_base &set_data_callback(Object &&cb) { return m_data_cb.set_callback(std::forward<Object>(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
|
Loading…
Reference in New Issue
Block a user