From b02df00ba0ebce74c7dce7c1732be03346be80c8 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Wed, 21 Aug 2019 14:41:27 +0200 Subject: mindset: Add modules, implement stereo [O. Galibert] --- src/mame/drivers/mindset.cpp | 181 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 179 insertions(+), 2 deletions(-) diff --git a/src/mame/drivers/mindset.cpp b/src/mame/drivers/mindset.cpp index 433ae20c6cd..584f945c7c1 100644 --- a/src/mame/drivers/mindset.cpp +++ b/src/mame/drivers/mindset.cpp @@ -15,6 +15,164 @@ #include "mindset.lh" + +class mindset_module_interface: public device_t { +public: + virtual void map(address_map &map) = 0; + +protected: + mindset_module_interface(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); +}; + +mindset_module_interface::mindset_module_interface(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock) +{ +} + +class mindset_module: public device_t, + public device_slot_interface +{ +public: + template + mindset_module(const machine_config &mconfig, const char *tag, device_t *owner, T &&opts, const char *dflt, bool fixed = false) + : mindset_module(mconfig, tag, owner, 0) + { + option_reset(); + opts(*this); + set_default_option(dflt); + set_fixed(fixed); + } + mindset_module(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + virtual ~mindset_module() = default; + + void map(address_space &space, offs_t base); + +protected: + virtual void device_validity_check(validity_checker &valid) const override; + virtual void device_start() override; +}; + +DEFINE_DEVICE_TYPE(MINDSET_MODULE, mindset_module, "mindset_module", "MINDSET module") + +mindset_module::mindset_module(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, MINDSET_MODULE, tag, owner, clock), + device_slot_interface(mconfig, *this) +{ +} + +void mindset_module::device_validity_check(validity_checker &valid) const +{ + device_t *const carddev = get_card_device(); + if (carddev && !dynamic_cast(carddev)) + osd_printf_error("Card device %s (%s) does not implement mindset_module_interface\n", carddev->tag(), carddev->name()); +} + +void mindset_module::device_start() +{ +} + +void mindset_module::map(address_space &space, offs_t base) +{ + mindset_module_interface *module = dynamic_cast(get_card_device()); + if(module) + space.install_device(base, base+0x3f, *module, &mindset_module_interface::map); +} + + +class mindset_sound_module: public mindset_module_interface { +public: + mindset_sound_module(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + virtual ~mindset_sound_module() = default; + + virtual void map(address_map &map) override; + +protected: + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + u8 m_p1, m_p2; + + required_device m_soundcpu; + required_device m_dac; + + void p1_w(u8 data); + void p2_w(u8 data); + void update_dac(); +}; + +DEFINE_DEVICE_TYPE(MINDSET_SOUND_MODULE, mindset_sound_module, "mindset_sound_module", "MINDSET stereo sound module") + +mindset_sound_module::mindset_sound_module(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + mindset_module_interface(mconfig, MINDSET_SOUND_MODULE, tag, owner, clock), + m_soundcpu(*this, "soundcpu"), + m_dac(*this, "dac") +{ +} + +void mindset_sound_module::device_start() +{ + save_item(NAME(m_p1)); + save_item(NAME(m_p2)); +} + +void mindset_sound_module::device_reset() +{ + m_p1 = 0x80; + m_p2 = 0; + m_dac->write(0x80); +} + +void mindset_sound_module::update_dac() +{ + // The p1 dac has the waveform (idle at 0x80), while the p2 one is used for the global volume (mute at 0x00, max at 0xff) + m_dac->write((s8(m_p1-0x80)*m_p2/255 + 0x80) & 0xff); +} + +void mindset_sound_module::p1_w(u8 data) +{ + m_p1 = data; + update_dac(); +} + +void mindset_sound_module::p2_w(u8 data) +{ + m_p2 = data; + update_dac(); +} + +void mindset_sound_module::map(address_map &map) +{ + map(0x00, 0x03).rw(m_soundcpu, FUNC(i8042_device::upi41_master_r), FUNC(i8042_device::upi41_master_w)).umask16(0x00ff); + map(0x00, 0x00).lr8("id", []() -> u8 { return 0x13; }); +} + +ROM_START(mindset_sound_module) + ROM_REGION(0x0800, "soundcpu", 0) + ROM_LOAD("253006-001.u16", 0, 0x800, CRC(7bea5edd) SHA1(30cdc0dedaa5246f4952df452a99ca22e3cd0636)) +ROM_END + +const tiny_rom_entry *mindset_sound_module::device_rom_region() const +{ + return ROM_NAME(mindset_sound_module); +} + +void mindset_sound_module::device_add_mconfig(machine_config &config) +{ + I8042(config, m_soundcpu, 12_MHz_XTAL/2); + m_soundcpu->p1_out_cb().set(FUNC(mindset_sound_module::p1_w)); + m_soundcpu->p2_out_cb().set(FUNC(mindset_sound_module::p2_w)); + + SPEAKER(config, "rspeaker").front_right(); + DAC_8BIT_R2R(config, m_dac, 0).add_route(ALL_OUTPUTS, "rspeaker", 0.5); + voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref")); + vref.add_route(0, m_dac, 1.0, DAC_VREF_POS_INPUT); + vref.add_route(0, m_dac, -1.0, DAC_VREF_NEG_INPUT); +} + + class mindset_state: public driver_device { public: @@ -39,6 +197,7 @@ protected: output_finder<> m_yellow_led; output_finder<> m_green_led; required_device m_dac; + required_device_array m_modules; memory_access_cache<1, 0, ENDIANNESS_LITTLE> *m_gcps; @@ -142,7 +301,8 @@ mindset_state::mindset_state(const machine_config &mconfig, device_type type, co m_red_led(*this, "red_led"), m_yellow_led(*this, "yellow_led"), m_green_led(*this, "green_led"), - m_dac(*this, "dac") + m_dac(*this, "dac"), + m_modules(*this, "m%d", 0U) { } @@ -193,6 +353,11 @@ void mindset_state::machine_start() void mindset_state::machine_reset() { + auto &space = m_maincpu->space(AS_IO); + space.unmap_readwrite(0x8080, 0x81ff); + for(int i=0; i<6; i++) + m_modules[i]->map(space, 0x8080 + 0x40*i); + m_fdc_intext = m_fdc_int = m_trap_int = m_fdc_drq = m_trap_drq = false; m_trap_pos = m_trap_len = 0; memset(m_trap_data, 0, sizeof(m_trap_data)); @@ -967,7 +1132,7 @@ u16 mindset_state::trap_dma_r(offs_t, u16 mem_mask) void mindset_state::maincpu_mem(address_map &map) { - map(0x00000, 0x7ffff).ram(); + map(0x00000, 0x3ffff).ram(); map(0xb8000, 0xbffff).ram().share("vram"); map(0xf8000, 0xfffff).rom().region("maincpu", 0); } @@ -1005,6 +1170,11 @@ static void pc_dd_floppies(device_slot_interface &device) device.option_add("525dd", FLOPPY_525_DD); } +static void mindset_modules(device_slot_interface &device) +{ + device.option_add("stereo", MINDSET_SOUND_MODULE); +} + void mindset_state::mindset(machine_config &config) { config.m_perfect_cpu_quantum = ":syscpu"; @@ -1057,6 +1227,13 @@ void mindset_state::mindset(machine_config &config) voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref")); vref.add_route(0, m_dac, 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, m_dac, -1.0, DAC_VREF_NEG_INPUT); + + MINDSET_MODULE(config, "m0", mindset_modules, "stereo", false); + MINDSET_MODULE(config, "m1", mindset_modules, nullptr, false); + MINDSET_MODULE(config, "m2", mindset_modules, nullptr, false); + MINDSET_MODULE(config, "m3", mindset_modules, nullptr, false); + MINDSET_MODULE(config, "m4", mindset_modules, nullptr, false); + MINDSET_MODULE(config, "m5", mindset_modules, nullptr, false); } static INPUT_PORTS_START(mindset) -- cgit v1.2.3