mu50: Enhance, add the swp00 [O. Galibert]

This commit is contained in:
Olivier Galibert 2019-04-28 13:53:25 +02:00
parent 33b1232c2b
commit 0ce1c644e3
4 changed files with 231 additions and 54 deletions

View File

@ -1506,6 +1506,18 @@ if (SOUNDS["IOPSPU"]~=null) then
}
end
---------------------------------------------------
--
--@src/devices/sound/swp00.h,SOUNDS["SWP00"] = true
---------------------------------------------------
if (SOUNDS["SWP00"]~=null) then
files {
MAME_DIR .. "src/devices/sound/swp00.cpp",
MAME_DIR .. "src/devices/sound/swp00.h",
}
end
---------------------------------------------------
--
--@src/devices/sound/swp20.h,SOUNDS["SWP20"] = true

102
src/devices/sound/swp00.cpp Normal file
View File

@ -0,0 +1,102 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
// Yamaha SWP00, rompler/dsp combo
#include "emu.h"
#include "swp00.h"
DEFINE_DEVICE_TYPE(SWP00, swp00_device, "swp00", "Yamaha SWP00 (TC170C120SF / XQ036A00) sound chip")
swp00_device::swp00_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, SWP00, tag, owner, clock),
device_sound_interface(mconfig, *this),
device_rom_interface(mconfig, *this, 25+2, ENDIANNESS_LITTLE, 32)
{
}
void swp00_device::device_add_mconfig(machine_config &config)
{
}
void swp00_device::device_start()
{
m_stream = stream_alloc(0, 2, 44100);
}
void swp00_device::device_reset()
{
}
void swp00_device::rom_bank_updated()
{
m_stream->update();
}
void swp00_device::map(address_map &map)
{
map(0x0000, 0x7ff).rw(FUNC(swp00_device::snd_r), FUNC(swp00_device::snd_w));
}
static u8 rr[0x20*0x20];
u8 swp00_device::snd_r(offs_t offset)
{
if(0) {
int chan = (offset >> 6) & 0x3f;
int slot = offset & 0x3f;
std::string preg = "-";
if(slot >= 0x21 && slot <= 0x2b && (slot & 1))
preg = util::string_format("fp%03x", (slot-0x21)/2 + 6*chan);
else if(slot == 0x30 || slot == 0x31)
preg = util::string_format("dt%02x", (slot-0x30) + 2*chan);
else if(slot == 0x0e || slot == 0x0f)
preg = util::string_format("ct%02x", (slot-0x0e) + 2*chan);
else
preg = util::string_format("%02x.%02x", chan, slot);
logerror("snd_r [%04x %04x] %-5s, %04x\n", offset, offset*2, preg, rr[offset]);
}
if(0 && offset == 0x080f)
machine().debug_break();
if(offset == 0x080f)
return 0;
return rr[offset];
}
void swp00_device::snd_w(offs_t offset, u8 data)
{
if(rr[offset] == data)
return;
rr[offset] = data;
int chan = (offset >> 6) & 0x1f;
int slot = offset & 0x3f;
std::string preg = "-";
#if 0
if(slot >= 0x21 && slot <= 0x2b && (slot & 1))
preg = util::string_format("fp%03x", (slot-0x21)/2 + 6*chan);
else if(slot == 0x0e || slot == 0x0f)
preg = util::string_format("sy%02x", (slot-0x0e) + 2*chan);
else if(slot == 0x30 || slot == 0x31)
preg = util::string_format("dt%02x", (slot-0x30) + 2*chan);
else if(slot == 0x38)
preg = util::string_format("vl%02x", chan);
else if(slot == 0x3e || slot == 0x3f)
preg = util::string_format("lf%02x", (slot-0x3e) + 2*chan);
else
#endif
preg = util::string_format("%02x.%02x", chan, slot);
logerror("snd_w [%04x %04x] %-5s, %02x\n", offset, offset*2, preg, data);
}
// Synthesis
void swp00_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
}

48
src/devices/sound/swp00.h Normal file
View File

@ -0,0 +1,48 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
// Yamaha SWP00, rompler/dsp combo
#ifndef DEVICES_SOUND_SWP00_H
#define DEVICES_SOUND_SWP00_H
#pragma once
#include "meg.h"
class swp00_device : public device_t, public device_sound_interface, public device_rom_interface
{
public:
swp00_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 33868800);
void map(address_map &map);
protected:
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;
virtual void rom_bank_updated() override;
virtual void device_add_mconfig(machine_config &config) override;
private:
// required_device<meg_embedded_device> m_meg;
sound_stream *m_stream;
// Generic catch-all
u8 snd_r(offs_t offset);
void snd_w(offs_t offset, u8 data);
inline auto &rchan(address_map &map, int idx) {
return map(idx*2, idx*2+1).select(0x7c0);
}
inline auto &rctrl(address_map &map, int idx) {
int slot = 0x20*(idx >> 1) | 0xe | (idx & 1);
return map(slot*2, slot*2+1);
}
};
DECLARE_DEVICE_TYPE(SWP00, swp00_device)
#endif

View File

@ -12,35 +12,38 @@
#include "bus/midi/midiinport.h"
#include "bus/midi/midioutport.h"
#include "cpu/h8/h83002.h"
#include "cpu/h8/h83003.h"
#include "machine/mulcd.h"
#include "sound/swp30.h"
#include "sound/meg.h"
#include "sound/swp00.h"
#include "debugger.h"
#include "speaker.h"
static INPUT_PORTS_START( mu50 )
PORT_START("P7")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Effect") PORT_CODE(KEYCODE_F)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Util") PORT_CODE(KEYCODE_U)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Part +") PORT_CODE(KEYCODE_CLOSEBRACE)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Part -") PORT_CODE(KEYCODE_OPENBRACE)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Mute/Solo") PORT_CODE(KEYCODE_S)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Edit") PORT_CODE(KEYCODE_E)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Play") PORT_CODE(KEYCODE_A)
PORT_START("O0")
PORT_BIT(0x83, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Play") PORT_CODE(KEYCODE_A)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Edit") PORT_CODE(KEYCODE_E)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Mute/Solo") PORT_CODE(KEYCODE_S)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Part -") PORT_CODE(KEYCODE_OPENBRACE)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Part +") PORT_CODE(KEYCODE_CLOSEBRACE)
PORT_START("P8")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Mode") PORT_CODE(KEYCODE_M)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Eq") PORT_CODE(KEYCODE_Q)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Exit") PORT_CODE(KEYCODE_BACKSPACE)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Select >") PORT_CODE(KEYCODE_STOP)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Select <") PORT_CODE(KEYCODE_COMMA)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Value +") PORT_CODE(KEYCODE_EQUALS)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Value -") PORT_CODE(KEYCODE_MINUS)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("O1")
PORT_BIT(0x83, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Util") PORT_CODE(KEYCODE_U)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Effect") PORT_CODE(KEYCODE_F)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Select <") PORT_CODE(KEYCODE_COMMA)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Select >") PORT_CODE(KEYCODE_STOP)
PORT_START("O2")
PORT_BIT(0x83, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Mode") PORT_CODE(KEYCODE_M)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Exit") PORT_CODE(KEYCODE_BACKSPACE)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Value -") PORT_CODE(KEYCODE_MINUS)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Value +") PORT_CODE(KEYCODE_EQUALS)
INPUT_PORTS_END
class mu50_state : public driver_device
@ -49,40 +52,30 @@ public:
mu50_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_mu50cpu(*this, "mu50cpu")
, m_swp30(*this, "swp30")
, m_swp00(*this, "swp00")
, m_lcd(*this, "lcd")
, m_ioport_p7(*this, "P7")
, m_ioport_p8(*this, "P8")
, m_ioport_o0(*this, "O0")
, m_ioport_o1(*this, "O1")
, m_ioport_o2(*this, "O2")
{ }
void mu50(machine_config &config);
private:
enum {
P2_LCD_RS = 0x01,
P2_LCD_RW = 0x02,
P2_LCD_ENABLE = 0x04
};
enum {
P6_LCD_RS = 0x04,
P6_LCD_RW = 0x02,
P6_LCD_ENABLE = 0x01
};
enum {
PA_LCD_RS = 0x02,
PA_LCD_ENABLE = 0x20,
PA_LCD_RW = 0x40
};
required_device<h83002_device> m_mu50cpu;
required_device<swp30_device> m_swp30;
required_device<h83003_device> m_mu50cpu;
required_device<swp00_device> m_swp00;
required_device<mulcd_device> m_lcd;
required_ioport m_ioport_p7;
required_ioport m_ioport_p8;
required_ioport m_ioport_o0;
required_ioport m_ioport_o1;
required_ioport m_ioport_o2;
u8 cur_p6, cur_pa, cur_pb;
u8 cur_p6, cur_pa, cur_pb, cur_pc;
u16 adc_zero_r();
u16 adc_ar_r();
@ -96,6 +89,8 @@ private:
u16 pa_r();
void pb_w(u16 data);
u16 pb_r();
void pc_w(u16 data);
u16 pc_r();
void mu50_iomap(address_map &map);
void mu50_map(address_map &map);
@ -105,13 +100,14 @@ private:
void mu50_state::machine_start()
{
cur_p6 = cur_pa = cur_pb = 0xff;
cur_p6 = cur_pa = cur_pb = cur_pc = 0xff;
}
void mu50_state::mu50_map(address_map &map)
{
map(0x000000, 0x07ffff).rom().region("mu50cpu", 0);
map(0x200000, 0x20ffff).ram(); // 64K work RAM
map(0x400000, 0x400fff).m(m_swp00, FUNC(swp00_device::map)).umask16(0xff00);
}
// Grounded adc input
@ -120,13 +116,13 @@ u16 mu50_state::adc_zero_r()
return 0;
}
// Analog input right (also sent to the swp)
// Analog input right (not sent to the swp)
u16 mu50_state::adc_ar_r()
{
return 0;
}
// Analog input left (also sent to the swp)
// Analog input left (not sent to the swp)
u16 mu50_state::adc_al_r()
{
return 0;
@ -179,6 +175,11 @@ void mu50_state::pa_w(u16 data)
cur_pa = data;
}
void mu50_state::pc_w(u16 data)
{
cur_pc = data;
}
u16 mu50_state::pa_r()
{
if((cur_p6 & P6_LCD_ENABLE)) {
@ -194,25 +195,38 @@ u16 mu50_state::pa_r()
return cur_pa;
}
u16 mu50_state::pc_r()
{
u16 res = cur_pc | 0x7c;
if(!(cur_pc & 0x01))
res &= m_ioport_o0->read();
if(!(cur_pc & 0x02))
res &= m_ioport_o1->read();
if(!(cur_pc & 0x80))
res &= m_ioport_o2->read();
return res;
}
void mu50_state::mu50_iomap(address_map &map)
{
map(h8_device::PORT_6, h8_device::PORT_6).rw(FUNC(mu50_state::p6_r), FUNC(mu50_state::p6_w));
map(h8_device::PORT_A, h8_device::PORT_A).rw(FUNC(mu50_state::pa_r), FUNC(mu50_state::pa_w));
map(h8_device::PORT_B, h8_device::PORT_B).rw(FUNC(mu50_state::pb_r), FUNC(mu50_state::pb_w));
map(h8_device::PORT_C, h8_device::PORT_C).rw(FUNC(mu50_state::pc_r), FUNC(mu50_state::pc_w));
map(h8_device::ADC_0, h8_device::ADC_0).r(FUNC(mu50_state::adc_ar_r));
map(h8_device::ADC_1, h8_device::ADC_1).r(FUNC(mu50_state::adc_zero_r));
map(h8_device::ADC_1, h8_device::ADC_1).lr16("gnd", []() -> u16 { return 0; });
map(h8_device::ADC_2, h8_device::ADC_2).r(FUNC(mu50_state::adc_al_r));
map(h8_device::ADC_3, h8_device::ADC_3).r(FUNC(mu50_state::adc_zero_r));
map(h8_device::ADC_3, h8_device::ADC_3).lr16("gnd", []() -> u16 { return 0; });
map(h8_device::ADC_4, h8_device::ADC_4).r(FUNC(mu50_state::adc_midisw_r));
map(h8_device::ADC_5, h8_device::ADC_6).r(FUNC(mu50_state::adc_zero_r));
map(h8_device::ADC_5, h8_device::ADC_6).lr16("gnd", []() -> u16 { return 0; });
map(h8_device::ADC_6, h8_device::ADC_6).r(FUNC(mu50_state::adc_battery_r));
map(h8_device::ADC_7, h8_device::ADC_7).r(FUNC(mu50_state::adc_zero_r)); // inputmod from the gate array
map(h8_device::ADC_7, h8_device::ADC_7).lr16("gnd", []() -> u16 { return 0; });
}
void mu50_state::mu50(machine_config &config)
{
H83002(config, m_mu50cpu, 16_MHz_XTAL);
H83003(config, m_mu50cpu, 12_MHz_XTAL);
m_mu50cpu->set_addrmap(AS_PROGRAM, &mu50_state::mu50_map);
m_mu50cpu->set_addrmap(AS_IO, &mu50_state::mu50_iomap);
@ -221,10 +235,9 @@ void mu50_state::mu50(machine_config &config)
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
// In truth, swp00
SWP30(config, m_swp30);
m_swp30->add_route(0, "lspeaker", 1.0);
m_swp30->add_route(1, "rspeaker", 1.0);
SWP00(config, m_swp00);
m_swp00->add_route(0, "lspeaker", 1.0);
m_swp00->add_route(1, "rspeaker", 1.0);
auto &mdin_a(MIDI_PORT(config, "mdin_a"));
midiin_slot(mdin_a);
@ -243,7 +256,9 @@ ROM_START( mu50 )
ROM_REGION( 0x80000, "mu50cpu", 0 )
ROM_LOAD16_WORD_SWAP( "yamaha_mu50.bin", 0x000000, 0x080000, CRC(507168ad) SHA1(58c41f10d292cac35ef0e8f93029fbc4685df586) )
ROM_REGION( 0x1800000, "swp00", ROMREGION_ERASE00 )
ROM_REGION( 0x400000, "swp00", ROMREGION_ERASE00 )
ROM_LOAD( "xq057b00.ic18", 0x000000, 0x200000, NO_DUMP)
ROM_LOAD( "xq058b00.ic18", 0x200000, 0x200000, NO_DUMP)
ROM_END
CONS( 1995, mu50, 0, 0, mu50, mu50, mu50_state, empty_init, "Yamaha", "MU50", MACHINE_NOT_WORKING )