mirror of
https://github.com/holub/mame
synced 2025-06-06 04:43:45 +03:00
mu50: Enhance, add the swp00 [O. Galibert]
This commit is contained in:
parent
33b1232c2b
commit
0ce1c644e3
@ -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
102
src/devices/sound/swp00.cpp
Normal 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
48
src/devices/sound/swp00.h
Normal 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
|
@ -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 )
|
||||
|
Loading…
Reference in New Issue
Block a user