mu50: Add the effects and the nvram

new WORKING machine
-------------------
Yamaha MU50 [O. Galibert, Phil Bennett]
This commit is contained in:
Olivier Galibert 2023-10-22 20:04:22 +02:00
parent b72de1cf6e
commit e96df77695
3 changed files with 932 additions and 118 deletions

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,16 @@ protected:
virtual void device_add_mconfig(machine_config &config) override;
private:
// required_device<meg_embedded_device> m_meg;
template<size_t size> struct delay_block {
swp00_device *m_swp;
std::array<s32, size> &m_buffer;
delay_block(swp00_device *swp, std::array<s32, size> &buffer);
s32 r(int offreg) const;
s32 rlfo(int offreg, u32 phase, s32 delta_phase, int levelreg) const;
s32 rlfo2(int offreg, s32 offset) const;
void w(int offreg, s32 value) const;
};
sound_stream *m_stream;
@ -41,9 +50,14 @@ private:
static const std::array<u32, 4> lfo_shape_offset_saw;
static const std::array<u32, 4> lfo_shape_offset_tri;
// MEG reverb memory
std::array<s32, 0x20000> m_rev_buffer;
std::array<s32, 0x8000> m_cho_buffer;
std::array<s32, 0x20000> m_var_buffer;
// MEG registers
std::array<u16, 0x40> m_off;
std::array<u16, 0xc0> m_fp;
std::array<u16, 0x40> m_offset;
std::array<u16, 0xc0> m_const;
// AWM registers
std::array<u16, 0x20> m_lpf_info;
@ -87,6 +101,36 @@ private:
u8 m_state_adr;
u8 m_meg_control;
// MEG state
u32 m_buffer_offset;
s32 m_rev_vol, m_cho_vol, m_var_vol;
u32 m_var_lfo_phase;
s32 m_var_lfo_h_1, m_var_lfo_h_2;
s32 m_var_lfo1a, m_var_lfo2a, m_var_lfo3a, m_var_lfo4a;
s32 m_var_filter_1, m_var_filter_2, m_var_filter_3;
s32 m_var_filter_l_1, m_var_filter_l_2, m_var_filter_l_3;
s32 m_var_filter_r_1, m_var_filter_r_2, m_var_filter_r_3;
s32 m_var_filter2_1, m_var_filter2_2a, m_var_filter2_2b, m_var_filter2_3a, m_var_filter2_3b, m_var_filter2_4;
s32 m_var_filter3_1, m_var_filter3_2;
s32 m_var_filterp_l_1, m_var_filterp_l_2, m_var_filterp_l_3;
s32 m_var_filterp_l_4, m_var_filterp_l_5, m_var_filterp_l_6;
s32 m_var_filterp_r_1, m_var_filterp_r_2, m_var_filterp_r_3;
s32 m_var_filterp_r_4, m_var_filterp_r_5, m_var_filterp_r_6;
s32 m_var_h1, m_var_h2, m_var_h3, m_var_h4;
u32 m_cho_lfo_phase;
s32 m_cho_filter_l_1, m_cho_filter_l_2, m_cho_filter_l_3;
s32 m_cho_filter_r_1, m_cho_filter_r_2, m_cho_filter_r_3;
s32 m_rev_filter_1, m_rev_filter_2, m_rev_filter_3;
s32 m_rev_hist_a, m_rev_hist_b, m_rev_hist_c, m_rev_hist_d;
// Voice control
template<int sel> void lpf_info_w(offs_t offset, u8 data);
@ -138,10 +182,10 @@ private:
void state_adr_w(u8 data);
// MEG
void off_w(offs_t offset, u8 data);
u8 off_r(offs_t offset);
void fp_w(offs_t offset, u8 data);
u8 fp_r(offs_t offset);
void offset_w(offs_t offset, u8 data);
u8 offset_r(offs_t offset);
void const_w(offs_t offset, u8 data);
u8 const_r(offs_t offset);
void meg_control_w(u8 data);
u8 meg_control_r();
@ -173,6 +217,28 @@ private:
static s32 fpsub(s32 value, s32 step);
static s32 fpapply(s32 value, s32 sample);
static s32 lpffpapply(s32 value, s32 sample);
s32 rext(int reg) const;
static s32 m7v(s32 value, s32 mult);
s32 m7(s32 value, int reg) const;
static s32 m9v(s32 value, s32 mult);
s32 m9(s32 value, int reg) const;
s32 lfo_get_step(int reg) const;
void lfo_step(u32 &phase, int reg) const;
static u32 lfo_wrap(s32 phase, s32 delta);
static s32 lfo_saturate(s32 phase);
s32 lfo_wrap_reg(s32 phase, int deltareg) const;
void filtered_lfo_step(s32 &position, s32 phase, int deltareg, int postdeltareg, int scalereg, int feedbackreg);
s32 lfo_mod(s32 phase, int scalereg) const;
s32 lfo_scale(s32 phase, int scalereg) const;
s32 alfo(u32 phase, s32 delta_phase, int levelreg, int offsetreg, bool sub) const;
s32 sx(int reg) const;
double sx7(int reg) const;
double sx9(int reg) const;
static s32 saturate(s32 value);
};
DECLARE_DEVICE_TYPE(SWP00, swp00_device)

View File

@ -2,8 +2,16 @@
// copyright-holders:R. Belmont, Olivier Galibert
/*************************************************************************************
Yamaha MU-50 : 16-voice polyphonic/multitimbral General MIDI/GS/XG tone modules
Preliminary driver by R. Belmont and O. Galibert
Yamaha MU-50 : 16-part, 32-note polyphonic/multitimbral General MIDI/GS/XG
tone module
Driver by R. Belmont and O. Galibert
Cost-reduced version of the MU80, uses the SWP00 which is a single-chip
integrated version of the multi-chip SWP20. As a consequence has half the
voices, loses the parametric EQ and the AD inputs. The sample roms are also
smaller, and it only has one midi input.
A wavetable version exists as the DB50XG.
**************************************************************************************/
@ -14,6 +22,7 @@
#include "cpu/h8/h83003.h"
#include "mulcd.h"
#include "sound/swp00.h"
#include "machine/nvram.h"
#include "debugger.h"
#include "speaker.h"
@ -53,11 +62,13 @@ public:
mu50_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_mu50cpu(*this, "mu50cpu")
, m_nvram(*this, "ram")
, m_swp00(*this, "swp00")
, m_lcd(*this, "lcd")
, m_ioport_o0(*this, "O0")
, m_ioport_o1(*this, "O1")
, m_ioport_o2(*this, "O2")
, m_ram(*this, "ram")
{ }
void mu50(machine_config &config);
@ -70,11 +81,13 @@ private:
};
required_device<h83003_device> m_mu50cpu;
required_device<nvram_device> m_nvram;
required_device<swp00_device> m_swp00;
required_device<mulcd_device> m_lcd;
required_ioport m_ioport_o0;
required_ioport m_ioport_o1;
required_ioport m_ioport_o2;
required_shared_ptr<u16> m_ram;
u8 cur_p6, cur_pa, cur_pb, cur_pc;
@ -112,7 +125,7 @@ void mu50_state::machine_reset()
void mu50_state::mu50_map(address_map &map)
{
map(0x000000, 0x07ffff).rom().region("mu50cpu", 0);
map(0x200000, 0x20ffff).ram(); // 64K work RAM
map(0x200000, 0x20ffff).ram().share(m_ram); // 64K work RAM
map(0x400000, 0x4007ff).m(m_swp00, FUNC(swp00_device::map));
}
@ -131,7 +144,6 @@ u16 mu50_state::adc_al_r()
// Put the host switch to pure midi
u16 mu50_state::adc_midisw_r()
{
// -> 20948a
// 000-0bf: midi
// 0c0-1ff: pc2
// 200-37f: pc1
@ -236,6 +248,8 @@ void mu50_state::mu50(machine_config &config)
m_mu50cpu->read_port7().set_constant(0);
m_mu50cpu->read_port9().set_constant(0);
NVRAM(config, m_nvram, nvram_device::DEFAULT_NONE);
MULCD(config, m_lcd);
SPEAKER(config, "lspeaker").front_left();
@ -254,16 +268,23 @@ void mu50_state::mu50(machine_config &config)
m_mu50cpu->write_sci_tx<1>().set(mdout, FUNC(midi_port_device::write_txd));
}
#define ROM_LOAD16_WORD_SWAP_BIOS(bios,name,offset,length,hash) \
ROMX_LOAD(name, offset, length, hash, ROM_GROUPWORD | ROM_REVERSE | ROM_BIOS(bios))
ROM_START( mu50 )
ROM_REGION( 0x80000, "mu50cpu", 0 )
ROM_LOAD16_WORD_SWAP( "yamaha_mu50.bin", 0x000000, 0x080000, CRC(507168ad) SHA1(58c41f10d292cac35ef0e8f93029fbc4685df586) )
ROM_SYSTEM_BIOS( 0, "bios0", "xr174c0 (v1.05, Aug. 21, 1995)" )
ROM_LOAD16_WORD_SWAP_BIOS( 0, "xr174c0.ic7", 0x000000, 0x080000, CRC(902520a4) SHA1(9ca892920598f9fdf08544dac4c0e54e7d46ee3c) )
ROM_SYSTEM_BIOS( 1, "bios1", "? (v1.04, May 22, 1995)" )
ROM_LOAD16_WORD_SWAP_BIOS( 1, "yamaha_mu50.bin", 0x000000, 0x080000, CRC(507168ad) SHA1(58c41f10d292cac35ef0e8f93029fbc4685df586) )
ROM_REGION( 0x400000, "swp00", ROMREGION_ERASE00 )
ROM_LOAD( "xq730b0.ic9", 0x000000, 0x200000, CRC(d4adbc7e) SHA1(32f653c7644d060f5a6d63a435ae3a7412386d92) BAD_DUMP) // Use the db50xg roms for now
ROM_LOAD( "xq731b0.ic10", 0x200000, 0x200000, CRC(7b68f475) SHA1(adf68689b4842ec5bc9b0ea1bb99cf66d2dec4de) BAD_DUMP) // Note that they may be identical to the mu50 ones
ROM_REGION( 0x400000, "swp00", 0 )
// Identical to the db50xg roms
ROM_LOAD( "xq057c0.ic18", 0x000000, 0x200000, CRC(d4adbc7e) SHA1(32f653c7644d060f5a6d63a435ae3a7412386d92) )
ROM_LOAD( "xq058c0.ic19", 0x200000, 0x200000, CRC(7b68f475) SHA1(adf68689b4842ec5bc9b0ea1bb99cf66d2dec4de) )
ROM_END
} // anonymous namespace
CONS( 1995, mu50, 0, 0, mu50, mu50, mu50_state, empty_init, "Yamaha", "MU50", MACHINE_NOT_WORKING )
CONS( 1995, mu50, 0, 0, mu50, mu50, mu50_state, empty_init, "Yamaha", "MU50", 0 )