diff --git a/src/devices/cpu/m68000/tmp68301.cpp b/src/devices/cpu/m68000/tmp68301.cpp index 03d9d417cdf..dcbd3a4a4a7 100644 --- a/src/devices/cpu/m68000/tmp68301.cpp +++ b/src/devices/cpu/m68000/tmp68301.cpp @@ -688,7 +688,7 @@ void tmp68301_device::pmr_w(u8 data) u16 tmp68301_device::pdr_r() { - if(m_parallel_mode == 0) { + if(m_parallel_mode == 0 || m_parallel_mode == 1) { if(m_pdir == 0xffff) return m_pdr; return (m_pdr & m_pdir) | (m_parallel_r_cb() & ~m_pdir); @@ -704,7 +704,7 @@ void tmp68301_device::pdr_w(offs_t, u16 data, u16 mem_mask) if(m_pdr == old) return; // logerror("parallel data %04x\n", m_pdr); - if(m_parallel_mode == 0) { + if(m_parallel_mode == 0 || m_parallel_mode == 1) { if(m_pdir == 0x0000) return; m_parallel_w_cb(m_pdr & m_pdir); diff --git a/src/devices/cpu/sh/sh7042.cpp b/src/devices/cpu/sh/sh7042.cpp index 1ae31e7077c..5a468b85969 100644 --- a/src/devices/cpu/sh/sh7042.cpp +++ b/src/devices/cpu/sh/sh7042.cpp @@ -90,7 +90,14 @@ void sh7042_device::adcsr_w(u8 data) void sh7042_device::adcr_w(u8 data) { - logerror("adcr_w %02x\n", data); + static const char *const tg_modes[4] = { "soft", "mtu", "?", "external" }; + static const char *const buf_modes[4] = { "normal", "a->b", "a,b->c,d", "a->b->c->d" }; + logerror("adcr_w speed=%d trigger=%s mode=%s sampling=%s buffering=%s\n", + BIT(data, 6) ? "high" : "low", + tg_modes[(data >> 4) & 3], + BIT(data, 3) ? "scan" : "single", + BIT(data, 2) ? "simultaneous" : "normal", + buf_modes[data & 3]); m_adcr = data; } diff --git a/src/devices/sound/dspv.cpp b/src/devices/sound/dspv.cpp index cf14ead15d3..b0f4d8f3596 100644 --- a/src/devices/sound/dspv.cpp +++ b/src/devices/sound/dspv.cpp @@ -6,13 +6,16 @@ #include "emu.h" #include "dspv.h" -DEFINE_DEVICE_TYPE(DSPV, dspv_device, "dspv", "Yamaha DSPV audio simulation DSP (YSS217-F/") +DEFINE_DEVICE_TYPE(DSPV, dspv_device, "dspv", "Yamaha DSPV audio simulation DSP (YSS217-F)") dspv_device::dspv_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, DSPV, tag, owner, clock), device_sound_interface(mconfig, *this), - m_program_config("program", ENDIANNESS_BIG, 16, 16, -1, address_map_constructor(FUNC(dspv_device::prg_map), this)), - m_data_config("data", ENDIANNESS_BIG, 16, 14, -1, address_map_constructor(FUNC(dspv_device::data_map), this)) + m_prg1_config("prg1", ENDIANNESS_BIG, 64, 8, -3, address_map_constructor(FUNC(dspv_device::prg1_map), this)), + m_prg2_config("prg2", ENDIANNESS_BIG, 64, 8, -3, address_map_constructor(FUNC(dspv_device::prg2_map), this)), + m_data_config("data", ENDIANNESS_BIG, 16, 32, -1, address_map_constructor(FUNC(dspv_device::data_map), this)), + m_prg1(*this, "prg1"), + m_prg2(*this, "prg2") { } @@ -22,57 +25,74 @@ void dspv_device::map(address_map &map) map(0x02, 0x03).r(FUNC(dspv_device::status_r)); map(0x06, 0x07).w(FUNC(dspv_device::prg_adr_w)); - map(0x20, 0x21).w(FUNC(dspv_device::table_adrh_w)); - map(0x22, 0x23).w(FUNC(dspv_device::table_adrl_w)); - map(0x24, 0x25).w(FUNC(dspv_device::table_data_w)); - map(0x26, 0x27).w(FUNC(dspv_device::table_zero_w)); - map(0x40, 0x7f).w(FUNC(dspv_device::prg_data_w)); + map(0x12, 0x13).lw16(NAME([](u16 data) { })); + map(0x20, 0x21).w(FUNC(dspv_device::data_adrh_w)); + map(0x22, 0x23).w(FUNC(dspv_device::data_adrl_w)); + map(0x24, 0x25).w(FUNC(dspv_device::data_data_w)); + map(0x26, 0x27).w(FUNC(dspv_device::data_zero_w)); + map(0x38, 0x39).lr16(NAME([]() -> u16 { return 0; })); + map(0x40, 0x7f).rw(FUNC(dspv_device::prg_data_r), FUNC(dspv_device::prg_data_w)); } -void dspv_device::prg_map(address_map &map) +void dspv_device::prg1_map(address_map &map) { - map(0x0000, 0xffff).ram(); + map(0x00, 0xff).ram().share(m_prg1); +} + +void dspv_device::prg2_map(address_map &map) +{ + map(0x00, 0xff).ram().share(m_prg2); } void dspv_device::data_map(address_map &map) { - map(0x0000, 0x3fff).ram(); + map(0x00000, 0x03fff).ram(); + map(0x1c000, 0x1dfff).ram(); } -void dspv_device::table_adrh_w(u16 data) +void dspv_device::data_adrh_w(u16 data) { - m_table_adr = (m_table_adr & 0x0000ffff) | (data << 16); + m_data_adr = (m_data_adr & 0x0000ffff) | (data << 16); } -void dspv_device::table_adrl_w(u16 data) +void dspv_device::data_adrl_w(u16 data) { - m_table_adr = (m_table_adr & 0xffff0000) | data; + m_data_adr = (m_data_adr & 0xffff0000) | data; } -void dspv_device::table_data_w(u16 data) +void dspv_device::data_data_w(u16 data) { - if(m_table_adr >= 0x4000) - logerror("table_adr overflow!\n"); - m_data->write_word(m_table_adr, data); - m_table_adr++; + m_data->write_word(m_data_adr, data); + m_data_adr++; } -void dspv_device::table_zero_w(u16 data) +void dspv_device::data_zero_w(u16 data) { - if(data) - logerror("table_zero_w %04x\n", data); + logerror("data_zero_w %04x\n", data); } void dspv_device::prg_adr_w(u16 data) { - m_prg_adr = data; + u32 slot = BIT(data, 13, 3); + u32 len = BIT(data, 8, 5); + u32 address = BIT(data, 0, 8); + if(len == 0) + len = 0x20; + auto &prg = slot >= 4 ? m_prg2 : m_prg1; + u32 shift = (slot & 3)*16; + u64 mask = ~(u64(0xffff) << shift); + for(u32 i=0; i != len; i++) + prg[(i + address) & 0xff] = (prg[(i + address) & 0xff] & mask) | (u64(m_buffer[i]) << shift); } void dspv_device::prg_data_w(offs_t offset, u16 data) { - u16 adr = m_prg_adr + offset; - adr = (adr << 3) | (adr >> 13); - m_program->write_word(adr, data); + m_buffer[offset] = data; +} + +u16 dspv_device::prg_data_r(offs_t offset) +{ + return m_buffer[offset]; } u16 dspv_device::status_r() @@ -100,7 +120,6 @@ void dspv_device::sound_stream_update(sound_stream &stream, std::vector const &inputs, std::vector &outputs) override; private: - address_space_config m_program_config, m_data_config; - address_space *m_program, *m_data; + address_space_config m_prg1_config, m_prg2_config, m_data_config; + address_space *m_data; + + required_shared_ptr m_prg1, m_prg2; + + std::array m_buffer; u32 m_pc; int m_icount; - u32 m_table_adr; - u16 m_prg_adr; + u32 m_data_adr; u16 m_status; - // Table ram access - void table_adrh_w(u16 data); - void table_adrl_w(u16 data); - void table_data_w(u16 data); - void table_zero_w(u16 data); + // Data ram access + void data_adrh_w(u16 data); + void data_adrl_w(u16 data); + void data_data_w(u16 data); + void data_zero_w(u16 data); // Program ram access void prg_adr_w(u16 data); void prg_data_w(offs_t offset, u16 data); + u16 prg_data_r(offs_t offset); // Registers u16 status_r(); @@ -59,7 +63,8 @@ class dspv_device : public cpu_device, public device_sound_interface u16 snd_r(offs_t offset); void snd_w(offs_t offset, u16 data); - void prg_map(address_map &map); + void prg1_map(address_map &map); + void prg2_map(address_map &map); void data_map(address_map &map); }; diff --git a/src/devices/sound/dspvd.cpp b/src/devices/sound/dspvd.cpp index 3a2fd254cf6..2865958113a 100644 --- a/src/devices/sound/dspvd.cpp +++ b/src/devices/sound/dspvd.cpp @@ -21,9 +21,9 @@ u32 dspv_disassembler::opcode_alignment() const offs_t dspv_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - u16 opc = opcodes.r16(pc); - - util::stream_format(stream, "dc.w %04x", opc); + u64 opc = opcodes.r64(pc); + u64 mode = (params.r64(pc) >> 32) & 7; + util::stream_format(stream, "%x%016x", mode, opc); return 1 | SUPPORTED; } diff --git a/src/mame/yamaha/ymvl1.cpp b/src/mame/yamaha/ymvl1.cpp index 95f57567d7d..79d167ca438 100644 --- a/src/mame/yamaha/ymvl1.cpp +++ b/src/mame/yamaha/ymvl1.cpp @@ -5,9 +5,6 @@ // The VL1-m rackable version exists but we don't have the firmware -// Waiting on tx possible in serial 2, need to implement decent serial -// in the 68301 to go on - // https://www.synthxl.com/offwp/yamaha_vl1_m_service_manual.pdf // Address decode: @@ -15,25 +12,40 @@ // 3210 9876 5432 1098 7654 3210 // 1... .... 000. .... ..0. .... .w led -// 1... .... 011. .... ..0. .... .w pks +// 1... .... 010. .... ..0. .... r. pks // 1... .... 011. .... ..0. .... r. adc // -// 1... .... 1000 .... .... .... rw vop -// 1... .... 1010 .... .... .... rw glcd +// 1... .... 1000 .... .... .... rw vop (dspv #4) +// 1... .... 1010 .... .... .... rw lcd // 1... .... 1011 .... .... .... rw fdc // // 0100 0... .... .... .... .... rw raml // 0100 1... .... .... .... .... rw ramh -// 0101 0... .... .... .... .... rw ssel1 -// 0101 1... .... .... .... .... rw ssel2 -// -// 1... .... 1000 .... .... .... rw dvop -// 1... .... 1010 .... .... .... rw lcd -// 1... .... 1011 .... .... .... rw dfdc +// 0101 0... .... .... .... .... rw ssel1 (top gate array) +// 0101 1... .... .... .... .... rw ssel2 (bottom gate array) + +// Uses 4 dsp-v which each have two inputs and two outputs. Their +// stream inputs/outputs are connected thus: +// #1.2 -> #3.2 +// #2.1 -> #3.1 +// #3.1 -> #4.1 +// #3.2 -> #4.2 +// #4.1 -> dac + +// Uses 3 tmp68301. The main one controls dspv #4. The first subcpu +// controls dspvs #2 and #3, the second #1, Each subgroup is tucked +// behind a gate array, selected by ssel1/2. + +// There's also an undumped 63b01 dubbed "pks" which scans the +// switches and has one 8-bit port and an irq line that goes to the +// main tmp. #include "emu.h" #include "cpu/m68000/tmp68301.h" +#include "imagedev/floppy.h" +#include "machine/upd765.h" +#include "sound/dspv.h" #include "video/t6963c.h" namespace { @@ -44,29 +56,53 @@ class vl1_state : public driver_device vl1_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), - m_lcd(*this, "lcd") + m_subcpu1(*this, "subcpu1"), + m_subcpu2(*this, "subcpu2"), + m_dspv1(*this, "dspv1"), + m_dspv2(*this, "dspv2"), + m_dspv3(*this, "dspv3"), + m_dspv4(*this, "dspv4"), + m_lcd(*this, "lcd"), + m_fdc(*this, "fdc"), + m_mem_s1(*this, "subcpu1_ram"), + m_mem_s2(*this, "subcpu2_ram") { } void vl1(machine_config &config); protected: virtual void machine_start() override; + virtual void machine_reset() override; private: - required_device m_maincpu; + required_device m_maincpu, m_subcpu1, m_subcpu2; + required_device m_dspv1, m_dspv2, m_dspv3, m_dspv4; required_device m_lcd; + required_device m_fdc; - u16 m_led; + required_shared_ptr m_mem_s1, m_mem_s2; + u16 m_led, m_main_ctrl, m_sub1_ctrl, m_sub2_ctrl; void maincpu_map(address_map &map); + void subcpu1_map(address_map &map); + void subcpu2_map(address_map &map); + + u16 main_r(); + void main_w(u16 data); + u16 sub1_r(); + void sub1_w(u16 data); + u16 sub2_r(); + void sub2_w(u16 data); void led_w(u16 data); + + static void hd_floppy(device_slot_interface &device); }; void vl1_state::led_w(u16 data) { u8 activated = (((~m_led) & data) >> 8) & 0xf; - if(activated) { + if(activated && 0) { if(activated & 1) logerror("led.0 %02x\n", data & 0xff); if(activated & 2) @@ -79,23 +115,154 @@ void vl1_state::led_w(u16 data) m_led = data; } +// Parallel port: +// o 0-3: adsel 1-4 | breath controller adc & muxer +// o 4 : adst | +// i 5 : eoc | +// o 7 : inh | +// o 8-9: bshalt 1-2 +// i a : fdc irq +// i b : fdc hd out (hd floppy detection) +// i d-e: re 1-2 +// o f : reclr + +u16 vl1_state::main_r() +{ + if(0) + logerror("main_r\n"); + return m_main_ctrl; +} + +void vl1_state::main_w(u16 data) +{ + if(0) + logerror("main_w adsel=%x adst=%d inh=%d bshalt=%d reclr=%d\n", + BIT(data, 0, 4), + BIT(data, 4), + BIT(data, 7), + BIT(data, 8, 2), + BIT(data, 15)); + + m_main_ctrl = data; + m_subcpu1->set_input_line(INPUT_LINE_HALT, !BIT(data, 8)); + m_subcpu2->set_input_line(INPUT_LINE_HALT, !BIT(data, 9)); +} + +u16 vl1_state::sub1_r() +{ + return m_sub1_ctrl; +} + +void vl1_state::sub1_w(u16 data) +{ + if(1) + logerror("sub1_w dsp = %d %d\n", + BIT(data, 0), + BIT(data, 1)); + + m_sub1_ctrl = data; + m_dspv2->set_input_line(INPUT_LINE_RESET, !BIT(data, 0)); + m_dspv3->set_input_line(INPUT_LINE_RESET, !BIT(data, 1)); +} + +u16 vl1_state::sub2_r() +{ + return m_sub2_ctrl; +} + +void vl1_state::sub2_w(u16 data) +{ + if(1) + logerror("sub2_w dsp = %d\n", + BIT(data, 0)); + + m_sub2_ctrl = data; + m_dspv1->set_input_line(INPUT_LINE_RESET, !BIT(data, 0)); +} + void vl1_state::machine_start() +{ + save_item(NAME(m_main_ctrl)); + save_item(NAME(m_sub1_ctrl)); + save_item(NAME(m_sub2_ctrl)); + save_item(NAME(m_led)); +} + +void vl1_state::machine_reset() { m_led = 0; + m_main_ctrl = 0; + m_sub1_ctrl = 0; + m_sub2_ctrl = 0; + + m_subcpu1->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); + m_subcpu2->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); + m_dspv1->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + m_dspv2->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + m_dspv3->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + m_dspv4->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); } void vl1_state::maincpu_map(address_map &map) { map(0x000000, 0x0fffff).rom().region("maincpu", 0); map(0x400000, 0x4fffff).ram(); + map(0x500000, 0x53ffff).ram().share(m_mem_s1); + map(0x580000, 0x5bffff).ram().share(m_mem_s2); map(0x800000, 0x800001).w(FUNC(vl1_state::led_w)); + map(0x804000, 0x804000).lr8(NAME([]() -> u8 { return 0; })); // pks + map(0x806000, 0x806000).lr8(NAME([]() -> u8 { return 0; })); // adc + map(0x808000, 0x80807f).m(m_dspv4, FUNC(dspv_device::map)); map(0x80a000, 0x80a003).rw(m_lcd, FUNC(lm24014h_device::read), FUNC(lm24014h_device::write)).umask16(0x00ff); + map(0x80b000, 0x80b003).m(m_fdc, FUNC(hd63266f_device::map)).umask16(0x00ff); +} + +void vl1_state::subcpu1_map(address_map &map) +{ + map(0x000000, 0x03ffff).ram().share(m_mem_s1); + map(0x040000, 0x04007f).m(m_dspv2, FUNC(dspv_device::map)); + map(0x050000, 0x05007f).m(m_dspv3, FUNC(dspv_device::map)); +} + +void vl1_state::subcpu2_map(address_map &map) +{ + map(0x000000, 0x03ffff).ram().share(m_mem_s2); + map(0x040000, 0x04007f).m(m_dspv1, FUNC(dspv_device::map)); +} + + +void vl1_state::hd_floppy(device_slot_interface &device) +{ + device.option_add("35hd", FLOPPY_35_HD); } void vl1_state::vl1(machine_config &config) { TMP68301(config, m_maincpu, 16_MHz_XTAL); m_maincpu->set_addrmap(AS_PROGRAM, &vl1_state::maincpu_map); + m_maincpu->parallel_r_cb().set(FUNC(vl1_state::main_r)); + m_maincpu->parallel_w_cb().set(FUNC(vl1_state::main_w)); + m_maincpu->tx2_handler().set(m_subcpu1, FUNC(tmp68301_device::rx2_w)); + m_maincpu->tx2_handler().append(m_subcpu2, FUNC(tmp68301_device::rx2_w)); + + TMP68301(config, m_subcpu1, 16_MHz_XTAL); + m_subcpu1->set_addrmap(AS_PROGRAM, &vl1_state::subcpu1_map); + m_subcpu1->parallel_r_cb().set(FUNC(vl1_state::sub1_r)); + m_subcpu1->parallel_w_cb().set(FUNC(vl1_state::sub1_w)); + + TMP68301(config, m_subcpu2, 16_MHz_XTAL); + m_subcpu2->set_addrmap(AS_PROGRAM, &vl1_state::subcpu2_map); + m_subcpu2->parallel_r_cb().set(FUNC(vl1_state::sub2_r)); + m_subcpu2->parallel_w_cb().set(FUNC(vl1_state::sub2_w)); + + DSPV(config, m_dspv1, 24.576_MHz_XTAL); + DSPV(config, m_dspv2, 24.576_MHz_XTAL); + DSPV(config, m_dspv3, 24.576_MHz_XTAL); + DSPV(config, m_dspv4, 24.576_MHz_XTAL); + + HD63266F(config, m_fdc, 16_MHz_XTAL); + m_fdc->set_ready_line_connected(false); + FLOPPY_CONNECTOR(config, "fdc:0", hd_floppy, "35hd", floppy_image_device::default_pc_floppy_formats); LM24014H(config, m_lcd); }