From c7cbfc13f6247fc26860de47d58e593652c7a795 Mon Sep 17 00:00:00 2001 From: hap Date: Fri, 30 Dec 2022 13:19:03 +0100 Subject: [PATCH] New working systems ------------------- Sound FX Phasor [hap, =CO=Windler] --- src/devices/cpu/tms34010/tms34010.cpp | 12 +- src/devices/sound/dac.h | 1 + src/mame/handheld/hh_cop400.cpp | 16 +-- src/mame/handheld/hh_pic16.cpp | 195 +++++++++++++++++++++++++- src/mame/mame.lst | 1 + 5 files changed, 206 insertions(+), 19 deletions(-) diff --git a/src/devices/cpu/tms34010/tms34010.cpp b/src/devices/cpu/tms34010/tms34010.cpp index 729b6ed0bf6..161e20d7396 100644 --- a/src/devices/cpu/tms34010/tms34010.cpp +++ b/src/devices/cpu/tms34010/tms34010.cpp @@ -973,14 +973,14 @@ void tms340x0_device::set_pixel_function() const tms340x0_device::raster_op_func tms340x0_device::s_raster_ops[32] = { - nullptr, &tms340x0_device::raster_op_1 , &tms340x0_device::raster_op_2 , &tms340x0_device::raster_op_3, - &tms340x0_device::raster_op_4 , &tms340x0_device::raster_op_5 , &tms340x0_device::raster_op_6 , &tms340x0_device::raster_op_7, - &tms340x0_device::raster_op_8 , &tms340x0_device::raster_op_9 , &tms340x0_device::raster_op_10, &tms340x0_device::raster_op_11, + nullptr, &tms340x0_device::raster_op_1, &tms340x0_device::raster_op_2, &tms340x0_device::raster_op_3, + &tms340x0_device::raster_op_4, &tms340x0_device::raster_op_5, &tms340x0_device::raster_op_6, &tms340x0_device::raster_op_7, + &tms340x0_device::raster_op_8, &tms340x0_device::raster_op_9, &tms340x0_device::raster_op_10, &tms340x0_device::raster_op_11, &tms340x0_device::raster_op_12, &tms340x0_device::raster_op_13, &tms340x0_device::raster_op_14, &tms340x0_device::raster_op_15, &tms340x0_device::raster_op_16, &tms340x0_device::raster_op_17, &tms340x0_device::raster_op_18, &tms340x0_device::raster_op_19, - &tms340x0_device::raster_op_20, &tms340x0_device::raster_op_21, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, + &tms340x0_device::raster_op_20, &tms340x0_device::raster_op_21, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, }; diff --git a/src/devices/sound/dac.h b/src/devices/sound/dac.h index 405eabd50cd..d571806b30e 100644 --- a/src/devices/sound/dac.h +++ b/src/devices/sound/dac.h @@ -224,6 +224,7 @@ DAC_GENERATOR(DAC_2BIT_BINARY_WEIGHTED, dac_2bit_binary_weighted_device, DAC_GENERATOR(DAC_2BIT_R2R, dac_2bit_r2r_device, dac_byte_device_base, dac_mapper_unsigned, 2, dac_gain_r2r, "2-Bit R-2R DAC", "dac_2bit_r2r") DAC_GENERATOR(DAC_2BIT_ONES_COMPLEMENT, dac_2bit_ones_complement_device, dac_byte_device_base, dac_mapper_ones_complement, 2, 1.0, "2-Bit Ones Complement DAC", "dac_2bit_oc") DAC_GENERATOR(DAC_3BIT_BINARY_WEIGHTED, dac_3bit_binary_weighted_device, dac_byte_device_base, dac_mapper_unsigned, 3, dac_gain_bw, "3-Bit Binary Weighted DAC", "dac_3bit_bw") +DAC_GENERATOR(DAC_3BIT_R2R, dac_3bit_r2r_device, dac_byte_device_base, dac_mapper_unsigned, 3, dac_gain_r2r, "3-Bit R-2R DAC", "dac_3bit_r2r") DAC_GENERATOR(DAC_4BIT_BINARY_WEIGHTED, dac_4bit_binary_weighted_device, dac_byte_device_base, dac_mapper_unsigned, 4, dac_gain_bw, "4-Bit Binary Weighted DAC", "dac_4bit_bw") DAC_GENERATOR(DAC_4BIT_R2R, dac_4bit_r2r_device, dac_byte_device_base, dac_mapper_unsigned, 4, dac_gain_r2r, "4-Bit R-2R DAC", "dac_4bit_r2r") DAC_GENERATOR(DAC_6BIT_BINARY_WEIGHTED, dac_6bit_binary_weighted_device, dac_byte_device_base, dac_mapper_unsigned, 6, dac_gain_bw, "6-Bit Binary Weighted DAC", "dac_6bit_bw") diff --git a/src/mame/handheld/hh_cop400.cpp b/src/mame/handheld/hh_cop400.cpp index 90e61bd4a68..f3e8335d674 100644 --- a/src/mame/handheld/hh_cop400.cpp +++ b/src/mame/handheld/hh_cop400.cpp @@ -1866,12 +1866,15 @@ class bship82_state : public hh_cop400_state { public: bship82_state(const machine_config &mconfig, device_type type, const char *tag) : - hh_cop400_state(mconfig, type, tag) + hh_cop400_state(mconfig, type, tag), + m_dac(*this, "dac") { } void bship82(machine_config &config); private: + required_device m_dac; + void write_d(u8 data); void write_g(u8 data); u8 read_l(); @@ -1889,9 +1892,9 @@ void bship82_state::write_d(u8 data) void bship82_state::write_g(u8 data) { - // G0-G2: speaker out via 3.9K, 2.2K, 1.0K resistor + // G0-G2: speaker out via 3.9K, 2.2K, 1.0K resistors // G3: enable speaker - m_speaker->level_w((data & 8) ? (data & 7) : 0); + m_dac->write((data & 8) ? (data & 7) : 0); } u8 bship82_state::read_l() @@ -1993,10 +1996,7 @@ void bship82_state::bship82(machine_config &config) // sound hardware SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, m_speaker); - static const double speaker_levels[8] = { 0.0, 1.0/7.0, 2.0/7.0, 3.0/7.0, 4.0/7.0, 5.0/7.0, 6.0/7.0, 1.0 }; - m_speaker->set_levels(8, speaker_levels); - m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25); + DAC_3BIT_R2R(config, m_dac).add_route(ALL_OUTPUTS, "mono", 0.25); } // roms @@ -2450,7 +2450,7 @@ void vidchal_state::vidchal(machine_config &config) // sound hardware SPEAKER(config, "mono").front_center(); - DAC_4BIT_BINARY_WEIGHTED(config, "dac").add_route(ALL_OUTPUTS, "mono", 0.125); + DAC_4BIT_R2R(config, "dac").add_route(ALL_OUTPUTS, "mono", 0.25); } // roms diff --git a/src/mame/handheld/hh_pic16.cpp b/src/mame/handheld/hh_pic16.cpp index 467c7f6f12a..90a21a86e72 100644 --- a/src/mame/handheld/hh_pic16.cpp +++ b/src/mame/handheld/hh_pic16.cpp @@ -31,9 +31,10 @@ known chips: *192 1650 19??, phone dialer (have dump) *255 1655 19??, talking clock (have dump) *518 1650A 19??, GI Teleview Control Chip (features differ per program) - *519 1650A 19??, " - *532 1650A 19??, " - *533 1650A 19??, " + *519 1650A 19??, GI Teleview Control Chip + @522 1655A 1981, Electroplay Sound FX Phasor + *532 1650A 19??, GI Teleview Control Chip + *533 1650A 19??, GI Teleview Control Chip *536 1650 1982, GI Teleview Autodialer/Terminal Identifier (* means undumped unless noted, @ denotes it's in this driver) @@ -48,6 +49,8 @@ ROM source notes when dumped from another title, but confident it's the same: TODO: - tweak MCU frequency for games when video/audio recording surfaces(YouTube etc.) - ttfball: discrete sound part, for volume gating? +- sfxphasor default music mode should have volume decay, I can't get it working + without breaking sound effects or command C (volume decay with values 15 and up) - what's the relation between drdunk and hccbaskb? Probably made by the same Hong Kong subcontractor? I presume Toytronic. - uspbball and pabball internal artwork @@ -60,6 +63,7 @@ TODO: #include "video/pwm.h" #include "machine/clock.h" #include "machine/timer.h" +#include "sound/dac.h" #include "sound/flt_vol.h" #include "sound/spkrdev.h" @@ -92,7 +96,8 @@ public: m_inputs(*this, "IN.%u", 0) { } - virtual DECLARE_INPUT_CHANGED_MEMBER(reset_button); + DECLARE_INPUT_CHANGED_MEMBER(reset_button); + DECLARE_INPUT_CHANGED_MEMBER(power_button); protected: virtual void machine_start() override; @@ -113,6 +118,7 @@ protected: u16 read_inputs(int columns, u16 colmask = ~0); u8 read_rotated_inputs(int columns, u8 rowmask = ~0); + void set_power(bool state); }; @@ -130,6 +136,7 @@ void hh_pic16_state::machine_start() void hh_pic16_state::machine_reset() { + set_power(true); } @@ -175,6 +182,19 @@ INPUT_CHANGED_MEMBER(hh_pic16_state::reset_button) m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? ASSERT_LINE : CLEAR_LINE); } +INPUT_CHANGED_MEMBER(hh_pic16_state::power_button) +{ + set_power((bool)param); +} + +void hh_pic16_state::set_power(bool state) +{ + m_maincpu->set_input_line(INPUT_LINE_RESET, state ? CLEAR_LINE : ASSERT_LINE); + + if (m_display && !state) + m_display->clear(); +} + /*************************************************************************** @@ -390,7 +410,7 @@ static INPUT_PORTS_START( pabball ) PORT_CONFSETTING( 0x20, "2" ) PORT_START("RESET") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_pic16_state, reset_button, 0) PORT_NAME("P1 Reset") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, pabball_state, reset_button, 0) PORT_NAME("P1 Reset") INPUT_PORTS_END void pabball_state::pabball(machine_config &config) @@ -423,6 +443,169 @@ ROM_END +/*************************************************************************** + + Electroplay Sound FX Phasor + * PIC 1655A-522 + * 3-bit sound with volume decay + + It's a toy synthesizer. When in music mode, the user can create custom + sounds with the F key, other keys are music notes. To put it briefly, + commands A,B are for vibrato, C is for volume decay, and D,E,F change + the timbre. + + Paste example (must be in music mode): F11A F3B F4C F3D F3E F6F + +***************************************************************************/ + +class sfxphasor_state : public hh_pic16_state +{ +public: + sfxphasor_state(const machine_config &mconfig, device_type type, const char *tag) : + hh_pic16_state(mconfig, type, tag), + m_dac(*this, "dac"), + m_volume(*this, "volume") + { } + + void sfxphasor(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + required_device m_dac; + required_device m_volume; + + void write_b(u8 data); + void write_c(u8 data); + u8 read_c(); + + TIMER_DEVICE_CALLBACK_MEMBER(speaker_decay_sim); + double m_speaker_volume = 0.0; +}; + +void sfxphasor_state::machine_start() +{ + hh_pic16_state::machine_start(); + save_item(NAME(m_speaker_volume)); +} + +// handlers + +TIMER_DEVICE_CALLBACK_MEMBER(sfxphasor_state::speaker_decay_sim) +{ + m_speaker_volume = std::clamp(m_speaker_volume, 0.0001, 1.0); + m_volume->flt_volume_set_volume(m_speaker_volume); + + // volume goes down while B3 is low + if (~m_b & 8) + m_speaker_volume /= 1.0001; + + // volume goes up while B3 is high + else + m_speaker_volume *= 1.0013; +} + +void sfxphasor_state::write_b(u8 data) +{ + // B2: trigger power off + if (~m_b & data & 4) + set_power(false); + + // B0: trigger speaker on + if (~m_b & data & 1) + m_volume->flt_volume_set_volume(m_speaker_volume = 1.0); + + // B5-B7: speaker out via 68K, 12K, 1K resistors + m_dac->write(data >> 5 & 7); + + m_b = data; +} + +void sfxphasor_state::write_c(u8 data) +{ + m_c = data; +} + +u8 sfxphasor_state::read_c() +{ + // C0-C3: multiplexed inputs from C4-C7 + m_inp_mux = m_c >> 4 & 0xf; + u8 lo = read_inputs(4, 0xf); + + // C4-C7: multiplexed inputs from C0-C3 + m_inp_mux = m_c & 0xf; + u8 hi = read_rotated_inputs(4, 0xf); + + return lo | hi << 4; +} + +// config + +static INPUT_PORTS_START( sfxphasor ) + PORT_START("IN.0") // C4 port C + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR('4') PORT_NAME("4 / Locomotive") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0') PORT_NAME("0 / Helicopter") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR('8') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + + PORT_START("IN.1") // C5 port C + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('5') PORT_NAME("5 / Bee") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1') PORT_NAME("1 / Telephone") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('9') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') + + PORT_START("IN.3") // C7 port C + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR('6') PORT_NAME("6 / Boat") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR('2') PORT_NAME("2 / Race Car") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') + + PORT_START("IN.2") // C6 port C + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('7') PORT_NAME("7 / Police Car") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('3') PORT_NAME("3 / UFO") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR('F') PORT_CHAR(13) PORT_NAME("F / Enter") + + PORT_START("IN.4") // port A + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_CONFNAME( 0x02, 0x02, "Auto Power Off" ) // MCU pin, not a switch + PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) + PORT_CONFSETTING( 0x02, DEF_STR( On ) ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_NAME("On / Sounds") PORT_CHANGED_MEMBER(DEVICE_SELF, sfxphasor_state, power_button, true) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_NAME("On / Music") PORT_CHANGED_MEMBER(DEVICE_SELF, sfxphasor_state, power_button, true) +INPUT_PORTS_END + +void sfxphasor_state::sfxphasor(machine_config &config) +{ + // basic machine hardware + PIC1655(config, m_maincpu, 1000000); // approximation - RC osc. R=10K+VR, C=47pF + m_maincpu->read_a().set_ioport("IN.4"); + m_maincpu->write_b().set(FUNC(sfxphasor_state::write_b)); + m_maincpu->write_c().set(FUNC(sfxphasor_state::write_c)); + m_maincpu->read_c().set(FUNC(sfxphasor_state::read_c)); + + // no visual feedback! + + // sound hardware + SPEAKER(config, "mono").front_center(); + DAC_3BIT_R2R(config, m_dac).add_route(ALL_OUTPUTS, "volume", 0.25); + FILTER_VOLUME(config, m_volume).add_route(ALL_OUTPUTS, "mono", 1.0); + + TIMER(config, "speaker_decay").configure_periodic(FUNC(sfxphasor_state::speaker_decay_sim), attotime::from_usec(10)); +} + +// roms + +ROM_START( sfxphasor ) + ROM_REGION( 0x0400, "maincpu", 0 ) + ROM_LOAD( "pic_1655a-522", 0x0000, 0x0400, CRC(0af77e83) SHA1(49b089681149254041c14a740cad19a619725c3c) ) +ROM_END + + + + + /*************************************************************************** GAF Melody Madness @@ -1944,6 +2127,8 @@ CONS( 1979, touchme, 0, 0, touchme, touchme, touchme_state, empty_ CONS( 1979, pabball, 0, 0, pabball, pabball, pabball_state, empty_init, "Caprice / Calfax", "Pro-Action Baseball", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING ) +CONS( 1981, sfxphasor, 0, 0, sfxphasor, sfxphasor, sfxphasor_state, empty_init, "Electroplay", "Sound FX Phasor", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) + CONS( 1980, melodym, 0, 0, melodym, melodym, melodym_state, empty_init, "GAF", "Melody Madness", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) CONS( 1979, maniac, 0, 0, maniac, maniac, maniac_state, empty_init, "Ideal Toy Corporation", "Maniac", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index ab7f7d6c696..d6c02c1da25 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -16661,6 +16661,7 @@ melodym // GAF matchme // Kingsford pabball // Caprice rockpin // Tiger Electronics +sfxphasor // Electroplay touchme // Atari ttfball // Toytronic ttfballa // Toytronic