From 1ff03c81e7a90ba25e254521a250640400be0bdf Mon Sep 17 00:00:00 2001 From: Felipe Correa da Silva Sanches Date: Sun, 2 Nov 2025 12:37:50 -0300 Subject: [PATCH] [Access Virus] Analog input knobs for Virus A & B --- src/devices/cpu/mcs51/sab80c535.cpp | 20 ++ src/devices/cpu/mcs51/sab80c535.h | 18 +- src/mame/access/acvirus.cpp | 135 ++++++++++++- src/mame/layout/virusb.lay | 284 +++++++++++++++++++++++++++- 4 files changed, 452 insertions(+), 5 deletions(-) diff --git a/src/devices/cpu/mcs51/sab80c535.cpp b/src/devices/cpu/mcs51/sab80c535.cpp index 2908f418a31b5..c34c3372e5c38 100644 --- a/src/devices/cpu/mcs51/sab80c535.cpp +++ b/src/devices/cpu/mcs51/sab80c535.cpp @@ -78,16 +78,34 @@ u8 sab80c535_device::p5_r() return m_p5 & m_port_in_cb[5](); } +void sab80c535_device::adcon_w(u8 data) +{ + m_adcon = data; +} + +u8 sab80c535_device::adcon_r() +{ + return m_adcon; +} + +u8 sab80c535_device::addat_r() +{ + return m_an_func[m_adcon & 7]() * 2; +} + void sab80c535_device::sfr_map(address_map &map) { i8052_device::sfr_map(map); + map(0xd8, 0xd8).rw(FUNC(sab80c535_device::adcon_r), FUNC(sab80c535_device::adcon_w)); + map(0xd9, 0xd9).r(FUNC(sab80c535_device::addat_r)); map(0xe8, 0xe8).rw(FUNC(sab80c535_device::p4_r), FUNC(sab80c535_device::p4_w)); map(0xf8, 0xf8).rw(FUNC(sab80c535_device::p5_r), FUNC(sab80c535_device::p5_w)); } sab80c535_device::sab80c535_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : i8052_device(mconfig, SAB80C535, tag, owner, clock, 0) + , m_an_func(*this, 0) { } @@ -96,6 +114,7 @@ void sab80c535_device::device_start() i8052_device::device_start(); save_item(NAME(m_p4)); save_item(NAME(m_p5)); + save_item(NAME(m_adcon)); } void sab80c535_device::device_reset() @@ -103,6 +122,7 @@ void sab80c535_device::device_reset() i8052_device::device_reset(); m_p4 = 0xff; m_p5 = 0xff; + m_adcon = 0x00; } std::unique_ptr sab80c535_device::create_disassembler() diff --git a/src/devices/cpu/mcs51/sab80c535.h b/src/devices/cpu/mcs51/sab80c535.h index 50b077207ece1..5c0b2c1cef540 100644 --- a/src/devices/cpu/mcs51/sab80c535.h +++ b/src/devices/cpu/mcs51/sab80c535.h @@ -12,6 +12,15 @@ class sab80c535_device : public i8052_device // construction/destruction sab80c535_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + auto an0_func() { return m_an_func[0].bind(); } + auto an1_func() { return m_an_func[1].bind(); } + auto an2_func() { return m_an_func[2].bind(); } + auto an3_func() { return m_an_func[3].bind(); } + auto an4_func() { return m_an_func[4].bind(); } + auto an5_func() { return m_an_func[5].bind(); } + auto an6_func() { return m_an_func[6].bind(); } + auto an7_func() { return m_an_func[7].bind(); } + protected: virtual void device_start() override ATTR_COLD; virtual void device_reset() override ATTR_COLD; @@ -19,13 +28,20 @@ class sab80c535_device : public i8052_device virtual std::unique_ptr create_disassembler() override; virtual void sfr_map(address_map &map) override ATTR_COLD; + devcb_read8::array<8> m_an_func; + private: - u8 m_p4, m_p5; + u8 m_p4; + u8 m_p5; + u8 m_adcon; void p4_w(u8 data); u8 p4_r(); void p5_w(u8 data); u8 p5_r(); + void adcon_w(u8 data); + u8 adcon_r(); + u8 addat_r(); }; DECLARE_DEVICE_TYPE(SAB80C535, sab80c535_device) diff --git a/src/mame/access/acvirus.cpp b/src/mame/access/acvirus.cpp index a53a22cbe8649..ae4339f71b58c 100644 --- a/src/mame/access/acvirus.cpp +++ b/src/mame/access/acvirus.cpp @@ -90,7 +90,9 @@ class acvirus_state : public driver_device m_dsp(*this, "dsp"), m_rombank(*this, "rombank"), m_row(*this, "ROW%u", 0U), - m_scan(0) + m_knob(*this, "knob_%u", 0U), + m_scan(0), + m_an_select(0) { } void virusa(machine_config &config) ATTR_COLD; @@ -119,13 +121,17 @@ class acvirus_state : public driver_device u8 p1_r(); u8 p4_r(); void p1_w(u8 data); + void p3_w(u8 data); void p5_w(u8 data); u8 p402_r(); void palette_init(palette_device &palette) ATTR_COLD; + required_ioport_array<32> m_knob; + u8 m_scan; + u8 m_an_select; }; @@ -135,6 +141,7 @@ void acvirus_state::machine_start() m_rombank->set_entry(3); save_item(NAME(m_scan)); + save_item(NAME(m_an_select)); } void acvirus_state::machine_reset() @@ -154,6 +161,11 @@ void acvirus_state::p1_w(u8 data) m_lcdc->rs_w(BIT(data, 7)); } +void acvirus_state::p3_w(u8 data) +{ + m_an_select = (data >> 4) & 3; +} + u8 acvirus_state::p4_r() { return m_row[m_scan & 3]->read(); @@ -205,8 +217,17 @@ void acvirus_state::virusa(machine_config &config) m_maincpu->set_addrmap(AS_DATA, &acvirus_state::data_map); m_maincpu->port_in_cb<1>().set(FUNC(acvirus_state::p1_r)); m_maincpu->port_out_cb<1>().set(FUNC(acvirus_state::p1_w)); + m_maincpu->port_out_cb<3>().set(FUNC(acvirus_state::p3_w)); m_maincpu->port_in_cb<4>().set(FUNC(acvirus_state::p4_r)); m_maincpu->port_out_cb<5>().set(FUNC(acvirus_state::p5_w)); + m_maincpu->an0_func().set([this] { return m_knob[4*0 + m_an_select]->read(); }); + m_maincpu->an1_func().set([this] { return m_knob[4*1 + m_an_select]->read(); }); + m_maincpu->an2_func().set([this] { return m_knob[4*2 + m_an_select]->read(); }); + m_maincpu->an3_func().set([this] { return m_knob[4*3 + m_an_select]->read(); }); + m_maincpu->an4_func().set([this] { return m_knob[4*4 + m_an_select]->read(); }); + m_maincpu->an5_func().set([this] { return m_knob[4*5 + m_an_select]->read(); }); + m_maincpu->an6_func().set([this] { return m_knob[4*6 + m_an_select]->read(); }); + m_maincpu->an7_func().set([this] { return m_knob[4*7 + m_an_select]->read(); }); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD)); screen.set_refresh_hz(60); @@ -237,8 +258,17 @@ void acvirus_state::virusb(machine_config &config) m_maincpu->set_addrmap(AS_DATA, &acvirus_state::data_map); m_maincpu->port_in_cb<1>().set(FUNC(acvirus_state::p1_r)); m_maincpu->port_out_cb<1>().set(FUNC(acvirus_state::p1_w)); + m_maincpu->port_out_cb<3>().set(FUNC(acvirus_state::p3_w)); m_maincpu->port_in_cb<4>().set(FUNC(acvirus_state::p4_r)); m_maincpu->port_out_cb<5>().set(FUNC(acvirus_state::p5_w)); + m_maincpu->an0_func().set([this] { return m_knob[4*0 + m_an_select]->read(); }); + m_maincpu->an1_func().set([this] { return m_knob[4*1 + m_an_select]->read(); }); + m_maincpu->an2_func().set([this] { return m_knob[4*2 + m_an_select]->read(); }); + m_maincpu->an3_func().set([this] { return m_knob[4*3 + m_an_select]->read(); }); + m_maincpu->an4_func().set([this] { return m_knob[4*4 + m_an_select]->read(); }); + m_maincpu->an5_func().set([this] { return m_knob[4*5 + m_an_select]->read(); }); + m_maincpu->an6_func().set([this] { return m_knob[4*6 + m_an_select]->read(); }); + m_maincpu->an7_func().set([this] { return m_knob[4*7 + m_an_select]->read(); }); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD)); screen.set_refresh_hz(60); @@ -297,7 +327,108 @@ void acvirus_state::virusc(machine_config &config) } +INPUT_PORTS_START( virusa_knobs ) + PORT_START("knob_0") + PORT_ADJUSTER(64, "Master Volume") PORT_MINMAX(0, 127) + + PORT_START("knob_1") + PORT_ADJUSTER(64, "Definable 1") PORT_MINMAX(0, 127) + + PORT_START("knob_2") + PORT_ADJUSTER(64, "Definable 2") PORT_MINMAX(0, 127) + + PORT_START("knob_3") + PORT_ADJUSTER(64, "LFO 1: Rate") PORT_MINMAX(0, 127) + + PORT_START("knob_4") + PORT_ADJUSTER(64, "LFO 2: Rate") PORT_MINMAX(0, 127) + + PORT_START("knob_5") + PORT_ADJUSTER(64, "Osc 1: Shape") PORT_MINMAX(0, 127) + + PORT_START("knob_6") + PORT_ADJUSTER(64, "Osc 1: Wave/PW") PORT_MINMAX(0, 127) + + PORT_START("knob_7") + PORT_ADJUSTER(64, "Osc 2: Shape") PORT_MINMAX(0, 127) + + PORT_START("knob_8") + PORT_ADJUSTER(64, "Osc 2: Wave/PW") PORT_MINMAX(0, 127) + + PORT_START("knob_9") + PORT_ADJUSTER(64, "Osc 2 Semitone") PORT_MINMAX(0, 127) + + PORT_START("knob_10") + PORT_ADJUSTER(64, "Osc 2 Detune") PORT_MINMAX(0, 127) + + PORT_START("knob_11") + PORT_ADJUSTER(64, "Osc 2 FM Amount") PORT_MINMAX(0, 127) + + PORT_START("knob_12") + PORT_ADJUSTER(64, "Mixer Osc Bal") PORT_MINMAX(0, 127) + + PORT_START("knob_13") + PORT_ADJUSTER(64, "Mixer Sub Osc") PORT_MINMAX(0, 127) + + PORT_START("knob_14") + PORT_ADJUSTER(64, "Mixer Osc Volume") PORT_MINMAX(0, 127) + + PORT_START("knob_15") + PORT_ADJUSTER(64, "Value (Program)") PORT_MINMAX(0, 127) + + PORT_START("knob_16") + PORT_ADJUSTER(64, "Cutoff") PORT_MINMAX(0, 127) + + PORT_START("knob_17") + PORT_ADJUSTER(64, "Cutoff 2") PORT_MINMAX(0, 127) + + PORT_START("knob_18") + PORT_ADJUSTER(64, "Filter Attack") PORT_MINMAX(0, 127) + + PORT_START("knob_19") + PORT_ADJUSTER(64, "Amp Attack") PORT_MINMAX(0, 127) + + PORT_START("knob_20") + PORT_ADJUSTER(64, "Filter Resonance") PORT_MINMAX(0, 127) + + PORT_START("knob_21") + PORT_ADJUSTER(64, "Filter EnvAmount") PORT_MINMAX(0, 127) + + PORT_START("knob_22") + PORT_ADJUSTER(64, "Filter Key Follow") PORT_MINMAX(0, 127) + + PORT_START("knob_23") + PORT_ADJUSTER(64, "Filter Balance") PORT_MINMAX(0, 127) + + PORT_START("knob_24") + PORT_ADJUSTER(64, "Filter Decay") PORT_MINMAX(0, 127) + + PORT_START("knob_25") + PORT_ADJUSTER(64, "Filter Sustain") PORT_MINMAX(0, 127) + + PORT_START("knob_26") + PORT_ADJUSTER(64, "Filter Time") PORT_MINMAX(0, 127) + + PORT_START("knob_27") + PORT_ADJUSTER(64, "Filter Release") PORT_MINMAX(0, 127) + + PORT_START("knob_28") + PORT_ADJUSTER(64, "Amp Decay") PORT_MINMAX(0, 127) + + PORT_START("knob_29") + PORT_ADJUSTER(64, "Amp Sustain") PORT_MINMAX(0, 127) + + PORT_START("knob_30") + PORT_ADJUSTER(64, "Amp Time") PORT_MINMAX(0, 127) + + PORT_START("knob_31") + PORT_ADJUSTER(64, "Amp Release") PORT_MINMAX(0, 127) +INPUT_PORTS_END + + static INPUT_PORTS_START( virusa ) + PORT_INCLUDE( virusa_knobs ) + PORT_START("ROW0") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_CODE(KEYCODE_1) PORT_NAME("Key Follow") PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_CODE(KEYCODE_V) PORT_NAME("Multi") @@ -340,6 +471,8 @@ INPUT_PORTS_END static INPUT_PORTS_START( virusb ) + PORT_INCLUDE( virusa_knobs ) + PORT_START("ROW0") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_CODE(KEYCODE_1) PORT_NAME("LFO 1: Edit") PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_CODE(KEYCODE_V) PORT_NAME("Multi") diff --git a/src/mame/layout/virusb.lay b/src/mame/layout/virusb.lay index 1facfac9e88e3..c408792f1ff27 100644 --- a/src/mame/layout/virusb.lay +++ b/src/mame/layout/virusb.lay @@ -60,7 +60,22 @@ license:CC0-1.0 - + + + + + + + + + + + + + + + + @@ -69,10 +84,14 @@ license:CC0-1.0 + @@ -81,7 +100,7 @@ license:CC0-1.0 - + @@ -562,10 +581,18 @@ license:CC0-1.0 + + + + + + + + @@ -590,6 +617,8 @@ license:CC0-1.0 + + @@ -637,6 +666,8 @@ license:CC0-1.0 + + @@ -687,9 +718,13 @@ license:CC0-1.0 + + + + @@ -697,15 +732,23 @@ license:CC0-1.0 + + + + + + + + @@ -719,16 +762,26 @@ license:CC0-1.0 + + + + + + + + + + @@ -801,7 +854,9 @@ license:CC0-1.0 - + + + @@ -809,25 +864,37 @@ license:CC0-1.0 + + + + + + + + + + + + @@ -885,20 +952,30 @@ license:CC0-1.0 + + + + + + + + + + @@ -906,21 +983,222 @@ license:CC0-1.0 + + + + + + + + + + + +