diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 699573720dd..0c3aa380f70 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -3324,6 +3324,7 @@ files { MAME_DIR .. "src/mame/drivers/roland_tb303.cpp", MAME_DIR .. "src/mame/drivers/roland_tr606.cpp", MAME_DIR .. "src/mame/drivers/roland_tr707.cpp", + MAME_DIR .. "src/mame/drivers/roland_tr909.cpp", MAME_DIR .. "src/mame/drivers/roland_u20.cpp", MAME_DIR .. "src/mame/audio/bu3905.cpp", MAME_DIR .. "src/mame/audio/bu3905.h", diff --git a/src/mame/drivers/roland_tr909.cpp b/src/mame/drivers/roland_tr909.cpp new file mode 100644 index 00000000000..3b39c59fbd4 --- /dev/null +++ b/src/mame/drivers/roland_tr909.cpp @@ -0,0 +1,293 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Skeleton driver for Roland TR-909 drum machine. + +***************************************************************************/ + +#include "emu.h" +#include "bus/generic/slot.h" +#include "cpu/upd7810/upd7810.h" +#include "machine/nvram.h" + +class roland_tr909_state : public driver_device +{ +public: + roland_tr909_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_cartslot(*this, "cartslot") + , m_inputs(*this, "IN%u", 1U) + , m_porta(0) + , m_portb(0) + { + } + + void tr909(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + void dac1_w(u8 data); + void dac2_w(u8 data); + void dac3_w(u8 data); + void dac4_w(u8 data); + void dac5_w(u8 data); + void dac6_w(u8 data); + void dac7_w(u8 data); + void dac8_w(u8 data); + void trig1_w(u8 data); + void trig2_w(u8 data); + + void pa_w(u8 data); + void pb_w(u8 data); + u8 switches_r(); + u8 cart_sense_r(); + + void tr909_mem(address_map &map); + + required_device m_cartslot; + required_ioport_array<5> m_inputs; + + u8 m_porta; + u8 m_portb; +}; + + +void roland_tr909_state::machine_start() +{ + save_item(NAME(m_porta)); + save_item(NAME(m_portb)); +} + +void roland_tr909_state::machine_reset() +{ + dac1_w(0); + dac2_w(0); + dac3_w(0); + dac4_w(0); + dac5_w(0); + dac6_w(0); + dac7_w(0); + dac8_w(0); + trig1_w(0); + trig2_w(0); +} + + +void roland_tr909_state::dac1_w(u8 data) +{ + logerror("%s: DAC 1 = %02X\n", machine().describe_context(), data & 0x7e); +} + +void roland_tr909_state::dac2_w(u8 data) +{ + logerror("%s: DAC 2 = %02X\n", machine().describe_context(), data & 0x7e); +} + +void roland_tr909_state::dac3_w(u8 data) +{ + logerror("%s: DAC 3 = %02X\n", machine().describe_context(), data & 0x7e); +} + +void roland_tr909_state::dac4_w(u8 data) +{ + logerror("%s: DAC 4 = %02X\n", machine().describe_context(), data & 0x7e); +} + +void roland_tr909_state::dac5_w(u8 data) +{ + logerror("%s: DAC 5 = %02X\n", machine().describe_context(), data & 0x7e); +} + +void roland_tr909_state::dac6_w(u8 data) +{ + logerror("%s: DAC 6 = %02X\n", machine().describe_context(), data & 0x7e); +} + +void roland_tr909_state::dac7_w(u8 data) +{ + logerror("%s: DAC 7 = %02X\n", machine().describe_context(), data & 0x7e); +} + +void roland_tr909_state::dac8_w(u8 data) +{ + logerror("%s: DAC 8 = %02X\n", machine().describe_context(), data & 0x7e); +} + +void roland_tr909_state::trig1_w(u8 data) +{ + // D6 is unused + logerror("%s: Trigger 1 = %02X\n", machine().describe_context(), data & 0x3e); +} + +void roland_tr909_state::trig2_w(u8 data) +{ + logerror("%s: Trigger 2 = %02X\n", machine().describe_context(), data & 0x7e); +} + + +void roland_tr909_state::pa_w(u8 data) +{ + // TODO: LED matrix and 4511 digits + m_porta = data; +} + +void roland_tr909_state::pb_w(u8 data) +{ + // TODO: LED matrix, 4511 LE and tape outputs + m_portb = data; +} + +u8 roland_tr909_state::switches_r() +{ + u8 data = 0xff; + for (int i = 0; i < 5; i++) + if (!BIT(m_porta, i)) + data &= m_inputs[i]->read(); + + return data; +} + +u8 roland_tr909_state::cart_sense_r() +{ + // TODO + return 0; +} + + +void roland_tr909_state::tr909_mem(address_map &map) +{ + map(0x0000, 0x1fff).rom().region("firmware", 0); + map(0x2000, 0x3fff).ram().share("nvram"); + map(0x4000, 0x4000).mirror(0x1fff).r(FUNC(roland_tr909_state::switches_r)); + map(0x4001, 0x4001).mirror(0x1ff0).w(FUNC(roland_tr909_state::dac1_w)); + map(0x4002, 0x4002).mirror(0x1ff0).w(FUNC(roland_tr909_state::dac2_w)); + map(0x4003, 0x4003).mirror(0x1ff0).w(FUNC(roland_tr909_state::dac3_w)); + map(0x4004, 0x4004).mirror(0x1ff0).w(FUNC(roland_tr909_state::dac4_w)); + map(0x4005, 0x4005).mirror(0x1ff0).w(FUNC(roland_tr909_state::dac5_w)); + map(0x4006, 0x4006).mirror(0x1ff0).w(FUNC(roland_tr909_state::dac6_w)); + map(0x4007, 0x4007).mirror(0x1ff0).w(FUNC(roland_tr909_state::dac7_w)); + map(0x4008, 0x4008).mirror(0x1ff0).w(FUNC(roland_tr909_state::dac8_w)); + map(0x4009, 0x4009).mirror(0x1ff0).w(FUNC(roland_tr909_state::trig1_w)); + map(0x400a, 0x400a).mirror(0x1ff0).w(FUNC(roland_tr909_state::trig2_w)); + map(0x6000, 0x7fff).unmaprw(); // cartridge +} + + +static INPUT_PORTS_START(tr909) + PORT_START("IN1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW1") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW2") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW3") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW4") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW5") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW6") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW7") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW8") + + PORT_START("IN2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW9") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW10") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW11") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW12") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW13") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW14") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW15") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("SW16") + + PORT_START("IN3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Shift") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Scale") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Inst Select") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Shuffle/Flam") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Last Step") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Stop/Cont") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Start") + + PORT_START("IN4") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Clear") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Track 1") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Track 2") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Track 3") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Track 4") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Pattern 1") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Pattern 2") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Pattern 3") + + PORT_START("IN5") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Enter/Accent") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Tape Sync") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Cycle") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Available Meas") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Fwd") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Back") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Tempo") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Ext Inst") + + PORT_START("TEMPO") + PORT_BIT(0xff, IP_ACTIVE_HIGH, IPT_UNKNOWN) // TODO: analog + + PORT_START("TOTAL") + PORT_BIT(0xff, IP_ACTIVE_HIGH, IPT_UNKNOWN) // TODO: analog +INPUT_PORTS_END + + +static void ram_carts(device_slot_interface &device) +{ +} + +void roland_tr909_state::tr909(machine_config &config) +{ + upd7810_device &maincpu(UPD7810(config, "maincpu", 12_MHz_XTAL)); + maincpu.set_addrmap(AS_PROGRAM, &roland_tr909_state::tr909_mem); + maincpu.pa_out_cb().set(FUNC(roland_tr909_state::pa_w)); + maincpu.pb_out_cb().set(FUNC(roland_tr909_state::pb_w)); + //maincpu.pc_in_cb().set(FUNC(roland_tr909_state::tr909_portc_r)); + //maincpu.pc_out_cb().set(FUNC(roland_tr909_state::tr909_portc_w)); + maincpu.an0_func().set_ioport("TEMPO"); + maincpu.an1_func().set(FUNC(roland_tr909_state::cart_sense_r)); + maincpu.an2_func().set_constant(0); + maincpu.an3_func().set_ioport("TOTAL"); + maincpu.an4_func().set_constant(0); + maincpu.an5_func().set_constant(0); + maincpu.an6_func().set_constant(0); + maincpu.an7_func().set_constant(0); + + NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); // TC5565PL-15 + battery + + // no screen + + GENERIC_CARTSLOT(config, m_cartslot, ram_carts, "tr909_cart", "bin"); + + //SOFTWARE_LIST(config, "cart_list", "tr909"); +} + + +ROM_START(tr909) + ROM_REGION(0x2000, "firmware", 0) + //cpu is a D7811G 037 with 4096w of ROM + //mode pins are both pulled to 5v + + //version 0 and 1 firmware also exist + ROM_SYSTEM_BIOS(0, "v4", "v4.0") + ROMX_LOAD("tr909_v4.ic609", 0, 0x2000, CRC(a9b45f30) SHA1(b94374e2cd6b5a6c405da4fa7793c98c0a6015c4), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "v1", "v1.0") + ROMX_LOAD("tr909_v1.ic609", 0, 0x2000, CRC(bfb9682b) SHA1(bcd754900574d1861034af8056574ffa77db3067), ROM_BIOS(1)) + + //samples + ROM_REGION(0x8000, "hihat", 0) + ROM_LOAD("hn61256p__c43.ic69", 0, 0x8000, CRC(2aaae11b) SHA1(22a34d603e78673bb096f5e56a8971afe14d8fee)) + + ROM_REGION(0x8000, "crash", 0) + ROM_LOAD("hn61256p__c42.ic62", 0, 0x8000, CRC(dc61cf1a) SHA1(bc730107b0c391f4879c9777a3e85f3e57f3aad6)) + + ROM_REGION(0x8000, "ride", 0) + ROM_LOAD("hn61256p__c44.ic54", 0, 0x8000, CRC(01a9b435) SHA1(daa54c58c7e3ae3398f125568537ec82d5bd1dfd)) +ROM_END + + +SYST(1984, tr909, 0, 0, tr909, tr909, roland_tr909_state, empty_init, "Roland", "TR-909 Rhythm Composer", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index c5ba69cb6ff..cb95c798ba7 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -34846,6 +34846,9 @@ tr606 // Roland tr707 // tr727 // +@source:roland_tr909.cpp +tr909 // + @source:roland_u20.cpp u20 // u220 // diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 134f52d74a4..377208bcedd 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -795,6 +795,7 @@ roland_sc88.cpp roland_tb303.cpp roland_tr606.cpp roland_tr707.cpp +roland_tr909.cpp roland_u20.cpp rt1715.cpp rvoice.cpp