From 7e1795ae6bc0df52705172747860d4fceb0000d5 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Mon, 30 Aug 2021 23:05:02 +1000 Subject: More miscellaneous cleanup: emu/render.cpp: Use I/O filter for zlib decompression, avoiding the need to use zlib directly. audo/bally.cpp: Moved several constructors out of the header, fixed a save state issue, and made outputs use finders. exidy.cpp: Split up state class and reduced reliance on driver init functions. Changed various drivers to use output finders. --- scripts/target/mame/arcade.lua | 2 - src/emu/render.cpp | 75 ++- src/mame/audio/bally.cpp | 85 +++- src/mame/audio/bally.h | 41 +- src/mame/drivers/atari_s1.cpp | 25 +- src/mame/drivers/by17.cpp | 23 +- src/mame/drivers/by35.cpp | 21 +- src/mame/drivers/by6803.cpp | 53 +- src/mame/drivers/exidy.cpp | 1063 ++++++++++++++++++++++++++++++---------- src/mame/drivers/f-32.cpp | 2 +- src/mame/drivers/opwolf.cpp | 66 ++- src/mame/drivers/videopkr.cpp | 143 +++--- src/mame/includes/exidy.h | 156 ------ src/mame/video/exidy.cpp | 374 -------------- 14 files changed, 1091 insertions(+), 1038 deletions(-) delete mode 100644 src/mame/includes/exidy.h delete mode 100644 src/mame/video/exidy.cpp diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 03c1246c0e1..78658b1f6d3 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -1973,10 +1973,8 @@ files { MAME_DIR .. "src/mame/audio/circus.cpp", MAME_DIR .. "src/mame/video/circus.cpp", MAME_DIR .. "src/mame/drivers/exidy.cpp", - MAME_DIR .. "src/mame/includes/exidy.h", MAME_DIR .. "src/mame/audio/exidy.cpp", MAME_DIR .. "src/mame/audio/exidy.h", - MAME_DIR .. "src/mame/video/exidy.cpp", MAME_DIR .. "src/mame/drivers/exidy440.cpp", MAME_DIR .. "src/mame/includes/exidy440.h", MAME_DIR .. "src/mame/audio/exidy440.cpp", diff --git a/src/emu/render.cpp b/src/emu/render.cpp index 2c4541cb6b9..ec718d25df5 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -50,11 +50,10 @@ #include "ui/uimain.h" +#include "util/ioprocsfilter.h" #include "util/path.h" #include "util/xmlfile.h" -#include - #include @@ -2118,58 +2117,56 @@ void render_target::load_additional_layout_files(const char *basename, bool have bool render_target::load_layout_file(const char *dirname, const internal_layout &layout_data, device_t *device) { // +1 to ensure data is terminated for XML parser - auto tempout = make_unique_clear(layout_data.decompressed_size + 1); - - z_stream stream; - int zerr; - - // initialize the stream - memset(&stream, 0, sizeof(stream)); - stream.next_out = tempout.get(); - stream.avail_out = layout_data.decompressed_size; - - zerr = inflateInit(&stream); - if (zerr != Z_OK) + std::unique_ptr tempout(new (std::nothrow) u8 [layout_data.decompressed_size + 1]); + auto inflater(util::zlib_read(util::ram_read(layout_data.data, layout_data.compressed_size), 8192)); + if (!tempout || !inflater) { - osd_printf_error("render_target::load_layout_file: zlib initialization error\n"); + osd_printf_error("render_target::load_layout_file: not enough memory to decompress layout\n"); return false; } - // decompress this chunk - stream.next_in = (unsigned char *)layout_data.data; - stream.avail_in = layout_data.compressed_size; - zerr = inflate(&stream, Z_NO_FLUSH); - - // stop at the end of the stream - if (zerr == Z_STREAM_END) + size_t decompressed = 0; + do { - // OK - } - else if (zerr != Z_OK) - { - osd_printf_error("render_target::load_layout_file: zlib decompression error\n"); - inflateEnd(&stream); - return false; + size_t actual; + std::error_condition const err = inflater->read( + &tempout[decompressed], + layout_data.decompressed_size - decompressed, + actual); + decompressed += actual; + if (err) + { + osd_printf_error( + "render_target::load_layout_file: error decompressing layout (%s:%d %s)\n", + err.category().name(), + err.value(), + err.message()); + return false; + } + if (!actual && (layout_data.decompressed_size < decompressed)) + { + osd_printf_warning( + "render_target::load_layout_file: expected %u bytes of decompressed data but only got %u\n", + layout_data.decompressed_size, + decompressed); + break; + } } + while (layout_data.decompressed_size > decompressed); + inflater.reset(); - // clean up - zerr = inflateEnd(&stream); - if (zerr != Z_OK) - osd_printf_error("render_target::load_layout_file: zlib cleanup error\n"); - + tempout[decompressed] = 0U; util::xml::file::ptr rootnode(util::xml::file::string_read(reinterpret_cast(tempout.get()), nullptr)); tempout.reset(); // if we didn't get a properly-formatted XML file, record a warning and exit if (!load_layout_file(device ? *device : m_manager.machine().root_device(), *rootnode, m_manager.machine().options().art_path(), dirname)) { - osd_printf_warning("Improperly formatted XML string, ignoring\n"); + osd_printf_warning("render_target::load_layout_file: Improperly formatted XML string, ignoring\n"); return false; } - else - { - return true; - } + + return true; } bool render_target::load_layout_file(const char *dirname, const char *filename) diff --git a/src/mame/audio/bally.cpp b/src/mame/audio/bally.cpp index 7b5cdf494b3..61f7bf89d56 100644 --- a/src/mame/audio/bally.cpp +++ b/src/mame/audio/bally.cpp @@ -444,6 +444,28 @@ static INPUT_PORTS_START(cheap_squeak) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE3 ) PORT_NAME("Sound Test") PORT_CHANGED_MEMBER(DEVICE_SELF, bally_cheap_squeak_device, sw1, 0) INPUT_PORTS_END +bally_cheap_squeak_device::bally_cheap_squeak_device( + const machine_config &mconfig, + const char *tag, + device_t *owner, + uint32_t clock) : + bally_cheap_squeak_device(mconfig, BALLY_CHEAP_SQUEAK, tag, owner, clock) +{ } + +bally_cheap_squeak_device::bally_cheap_squeak_device( + const machine_config &mconfig, + device_type type, + const char *tag, + device_t *owner, + uint32_t clock) : + device_t(mconfig, type, tag, owner, clock), + device_mixer_interface(mconfig, *this), + m_cpu(*this, "cpu"), + m_dac(*this, "dac"), + m_sound_ack_w_handler(*this), + m_leds(*this, "sound_led%u", 0U) +{ } + ioport_constructor bally_cheap_squeak_device::device_input_ports() const { return INPUT_PORTS_NAME(cheap_squeak); @@ -451,8 +473,7 @@ ioport_constructor bally_cheap_squeak_device::device_input_ports() const INPUT_CHANGED_MEMBER(bally_cheap_squeak_device::sw1) { - if (newval != oldval) - m_cpu->set_input_line(INPUT_LINE_NMI, (newval ? ASSERT_LINE : CLEAR_LINE)); + m_cpu->set_input_line(INPUT_LINE_NMI, (newval ? ASSERT_LINE : CLEAR_LINE)); } //------------------------------------------------- @@ -517,6 +538,8 @@ void bally_cheap_squeak_device::device_add_mconfig(machine_config &config) void bally_cheap_squeak_device::device_start() { m_sound_ack_w_handler.resolve(); + m_leds.resolve(); + save_item(NAME(m_sound_select)); save_item(NAME(m_sound_int)); } @@ -557,8 +580,7 @@ void bally_cheap_squeak_device::out_p2_cb(uint8_t data) void bally_cheap_squeak_device::update_led() { // Either input or output can pull the led line high - bool led_state = m_sound_int || m_sound_ack; - machine().output().set_value("sound_led0", led_state); + m_leds[0] = m_sound_int || m_sound_ack; } @@ -566,6 +588,41 @@ void bally_cheap_squeak_device::update_led() // Squawk & Talk //************************************************************************** +bally_squawk_n_talk_device::bally_squawk_n_talk_device( + const machine_config &mconfig, + const char *tag, + device_t *owner, + uint32_t clock) : + bally_squawk_n_talk_device(mconfig, BALLY_SQUAWK_N_TALK, tag, owner, clock) +{ } + +bally_squawk_n_talk_device::bally_squawk_n_talk_device( + const machine_config &mconfig, + device_type type, + const char *tag, + device_t *owner, + uint32_t clock) : + device_t(mconfig, type, tag, owner, clock), + device_mixer_interface(mconfig, *this), + m_cpu(*this, "cpu"), + m_pia1(*this, "pia1"), + m_pia2(*this, "pia2"), + m_dac_filter(*this, "dac_filter"), + m_dac(*this, "dac"), + m_speech_filter(*this, "speech_filter"), + m_tms5200(*this, "tms5200") +{ } + +bally_squawk_n_talk_ay_device::bally_squawk_n_talk_ay_device( + const machine_config &mconfig, + const char *tag, + device_t *owner, + uint32_t clock) : + bally_squawk_n_talk_device(mconfig, BALLY_SQUAWK_N_TALK_AY, tag, owner, clock), + m_ay_filters(*this, "ay_filter%u", 0), + m_ay(*this, "ay") +{ } + //-------------------------------------------------------------------------- // IO ports //-------------------------------------------------------------------------- @@ -648,7 +705,7 @@ void bally_squawk_n_talk_device::device_add_mconfig(machine_config &config) PIA6821(config, m_pia2, 0); m_pia2->readpa_handler().set(FUNC(bally_squawk_n_talk_device::pia2_porta_r)); - m_pia2->ca2_handler().set(FUNC(bally_squawk_n_talk_device::pia2_ca2_w)); + m_pia2->ca2_handler().set_output("sound_led0"); m_pia2->irqa_handler().set(FUNC(bally_squawk_n_talk_device::pia_irq_w)); m_pia2->irqb_handler().set(FUNC(bally_squawk_n_talk_device::pia_irq_w)); @@ -696,15 +753,6 @@ uint8_t bally_squawk_n_talk_device::pia2_porta_r() return ~m_sound_select & 0x1f; } -//------------------------------------------------- -// pia2_ca2_w - PIA 2 CA2 writes -//------------------------------------------------- - -WRITE_LINE_MEMBER(bally_squawk_n_talk_device::pia2_ca2_w) -{ - machine().output().set_value("sound_led0", state); -} - //------------------------------------------------- // pia_irq_w - IRQ line state changes //------------------------------------------------- @@ -726,10 +774,11 @@ void bally_squawk_n_talk_ay_device::device_add_mconfig(machine_config &config) m_pia2->writepb_handler().set(FUNC(bally_squawk_n_talk_ay_device::pia2_portb_w)); m_pia2->cb2_handler().set(FUNC(bally_squawk_n_talk_ay_device::pia2_cb2_w)); - for (optional_device &filter : m_ay_filters) - // TODO: Calculate exact filter values. An AC filter is good enough for now - // and required as the chip likes to output a DC offset at idle. + // TODO: Calculate exact filter values. An AC filter is good enough for now + // and required as the chip likes to output a DC offset at idle. + for (auto &filter : m_ay_filters) FILTER_RC(config, filter).set_ac().add_route(ALL_OUTPUTS, *this, 1.0); + AY8910(config, m_ay, DERIVED_CLOCK(1, 4)); m_ay->add_route(0, "ay_filter0", 0.33); m_ay->add_route(1, "ay_filter1", 0.33); @@ -742,6 +791,8 @@ void bally_squawk_n_talk_ay_device::device_add_mconfig(machine_config &config) //------------------------------------------------- void bally_squawk_n_talk_ay_device::device_start() { + bally_squawk_n_talk_device::device_start(); + // Set volumes to a sane default. m_ay->set_volume(0, 0); m_ay->set_volume(1, 0); diff --git a/src/mame/audio/bally.h b/src/mame/audio/bally.h index 6d6fe670333..553e9b15144 100644 --- a/src/mame/audio/bally.h +++ b/src/mame/audio/bally.h @@ -205,9 +205,7 @@ public: const machine_config &mconfig, const char *tag, device_t *owner, - uint32_t clock = 3'579'545) : - bally_cheap_squeak_device(mconfig, BALLY_CHEAP_SQUEAK, tag, owner, clock) - { } + uint32_t clock = 3'579'545); auto sound_ack_w_handler() { return m_sound_ack_w_handler.bind(); } @@ -224,13 +222,7 @@ protected: device_type type, const char *tag, device_t *owner, - uint32_t clock) : - device_t(mconfig, type, tag, owner, clock), - device_mixer_interface(mconfig, *this), - m_cpu(*this, "cpu"), - m_dac(*this, "dac"), - m_sound_ack_w_handler(*this) - { } + uint32_t clock); // device-level overrides virtual void device_add_mconfig(machine_config &config) override; @@ -247,6 +239,7 @@ private: bool m_sound_ack; devcb_write_line m_sound_ack_w_handler; + output_finder<1> m_leds; // internal communications TIMER_CALLBACK_MEMBER(sound_select_sync); @@ -269,9 +262,7 @@ public: const machine_config &mconfig, const char *tag, device_t *owner, - uint32_t clock = 3'579'545) : - bally_squawk_n_talk_device(mconfig, BALLY_SQUAWK_N_TALK, tag, owner, clock) - { } + uint32_t clock = 3'579'545); // read/write DECLARE_INPUT_CHANGED_MEMBER(sw1); @@ -286,19 +277,7 @@ protected: device_type type, const char *tag, device_t *owner, - uint32_t clock) : - device_t(mconfig, type, tag, owner, clock), - device_mixer_interface(mconfig, *this), - m_cpu(*this, "cpu"), - m_pia1(*this, "pia1"), - m_pia2(*this, "pia2"), - m_dac_filter(*this, "dac_filter"), - m_dac(*this, "dac"), - m_speech_filter(*this, "speech_filter"), - m_tms5200(*this, "tms5200"), - m_ay_filters(*this, "ay_filter%u", 0), - m_ay(*this, "ay") - { } + uint32_t clock); // device-level overrides virtual void device_add_mconfig(machine_config &config) override; @@ -313,8 +292,6 @@ protected: required_device m_dac; required_device m_speech_filter; required_device m_tms5200; - optional_device_array m_ay_filters; - optional_device m_ay; uint8_t m_sound_select; @@ -325,7 +302,6 @@ private: TIMER_CALLBACK_MEMBER(sound_select_sync); TIMER_CALLBACK_MEMBER(sound_int_sync); void pia1_portb_w(uint8_t data); - DECLARE_WRITE_LINE_MEMBER(pia2_ca2_w); DECLARE_WRITE_LINE_MEMBER(pia_irq_w); }; @@ -337,9 +313,7 @@ public: const machine_config &mconfig, const char *tag, device_t *owner, - uint32_t clock = 3'579'545) : - bally_squawk_n_talk_device(mconfig, BALLY_SQUAWK_N_TALK_AY, tag, owner, clock) - { } + uint32_t clock = 3'579'545); protected: // device-level overrides @@ -353,6 +327,9 @@ private: bool m_bdir; uint8_t m_ay_data; + required_device_array m_ay_filters; + required_device m_ay; + void pia2_porta_w(uint8_t data); void pia2_portb_w(uint8_t data); DECLARE_WRITE_LINE_MEMBER(pia2_cb2_w); diff --git a/src/mame/drivers/atari_s1.cpp b/src/mame/drivers/atari_s1.cpp index 2dfab65b858..15f0f6536bb 100644 --- a/src/mame/drivers/atari_s1.cpp +++ b/src/mame/drivers/atari_s1.cpp @@ -75,6 +75,7 @@ public: , m_dac(*this, "dac") , m_switch(*this, "SWITCH.%u", 0) , m_digits(*this, "digit%u", 0U) + , m_player_lamps(*this, "text%u", 0U) { } void midearth(machine_config &config); @@ -82,8 +83,8 @@ public: void atarians(machine_config &config); protected: + virtual void machine_start() override; virtual void machine_reset() override; - virtual void machine_start() override { m_digits.resolve(); } private: uint8_t m1080_r(); @@ -121,6 +122,7 @@ private: required_device m_dac; required_ioport_array<10> m_switch; output_finder<78> m_digits; + output_finder<8> m_player_lamps; }; void atari_s1_state::atari_s1_map(address_map &map) @@ -384,26 +386,25 @@ uint8_t atari_s1_state::switch_r(offs_t offset) TIMER_DEVICE_CALLBACK_MEMBER( atari_s1_state::nmi ) { static const uint8_t patterns[16] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67, 0, 0, 0, 0, 0, 0 }; // 4511 + m_bit6++; if (m_t_c > 0x40) m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); else m_t_c++; - m_out_offs++; - m_out_offs &= 0x1f; - if ((m_out_offs & 3) == 3) + m_out_offs = (m_out_offs + 1) & 0x1f; + uint8_t const p_val = m_p_ram[m_out_offs]; + if ((m_out_offs & 0x03) == 0x03) { // Player number - char wordnum[8]; - sprintf(wordnum,"text%d",m_out_offs>>2); - output().set_value(wordnum, !BIT(patterns[m_p_ram[m_out_offs]&15], 6)); // uses 'g' segment + m_player_lamps[m_out_offs >> 2] = !BIT(patterns[p_val & 0x0f], 6); // uses 'g' segment } else { // Digits - m_digits[m_out_offs << 1] = patterns[m_p_ram[m_out_offs]>>4]; - m_digits[(m_out_offs << 1)+1] = patterns[m_p_ram[m_out_offs]&15]; + m_digits[(m_out_offs << 1) + 0] = patterns[p_val >> 4]; + m_digits[(m_out_offs << 1) + 1] = patterns[p_val & 0x0f]; } } @@ -445,6 +446,12 @@ void atari_s1_state::audiores_w(uint8_t data) } +void atari_s1_state::machine_start() +{ + m_digits.resolve(); + m_player_lamps.resolve(); +} + void atari_s1_state::machine_reset() { m_vol = 0; diff --git a/src/mame/drivers/by17.cpp b/src/mame/drivers/by17.cpp index 33074d0e79b..2df32735d9f 100644 --- a/src/mame/drivers/by17.cpp +++ b/src/mame/drivers/by17.cpp @@ -20,13 +20,18 @@ ToDo: #include "emu.h" #include "machine/genpin.h" + #include "cpu/m6800/m6800.h" #include "machine/6821pia.h" #include "machine/timer.h" + #include "by17.lh" #include "by17_pwerplay.lh" #include "by17_matahari.lh" + +namespace { + class by17_state : public genpin_class { public: @@ -118,7 +123,6 @@ private: DECLARE_WRITE_LINE_MEMBER(u10_cb2_w); DECLARE_READ_LINE_MEMBER(u11_ca1_r); DECLARE_READ_LINE_MEMBER(u11_cb1_r); - DECLARE_WRITE_LINE_MEMBER(u11_ca2_w); DECLARE_WRITE_LINE_MEMBER(u11_cb2_w); TIMER_DEVICE_CALLBACK_MEMBER(timer_z_freq); @@ -577,11 +581,6 @@ WRITE_LINE_MEMBER( by17_state::u10_cb2_w ) m_u10_cb2 = state; } -WRITE_LINE_MEMBER( by17_state::u11_ca2_w ) -{ - output().set_value("led0", state); -} - READ_LINE_MEMBER( by17_state::u11_ca1_r ) { return m_u11_ca1; @@ -1014,8 +1013,8 @@ void by17_state::by17(machine_config &config) m_pia_u10->readcb1_handler().set(FUNC(by17_state::u10_cb1_r)); m_pia_u10->ca2_handler().set(FUNC(by17_state::u10_ca2_w)); m_pia_u10->cb2_handler().set(FUNC(by17_state::u10_cb2_w)); - m_pia_u10->irqa_handler().set_inputline("maincpu", M6800_IRQ_LINE); - m_pia_u10->irqb_handler().set_inputline("maincpu", M6800_IRQ_LINE); + m_pia_u10->irqa_handler().set_inputline(m_maincpu, M6800_IRQ_LINE); + m_pia_u10->irqb_handler().set_inputline(m_maincpu, M6800_IRQ_LINE); TIMER(config, "timer_z_freq").configure_periodic(FUNC(by17_state::timer_z_freq), attotime::from_hz(100)); // Mains Line Frequency * 2 TIMER(config, m_zero_crossing_active_timer).configure_generic(FUNC(by17_state::timer_z_pulse)); // Active pulse length from Zero Crossing detector @@ -1025,10 +1024,10 @@ void by17_state::by17(machine_config &config) m_pia_u11->writepb_handler().set(FUNC(by17_state::u11_b_w)); m_pia_u11->readca1_handler().set(FUNC(by17_state::u11_ca1_r)); m_pia_u11->readcb1_handler().set(FUNC(by17_state::u11_cb1_r)); - m_pia_u11->ca2_handler().set(FUNC(by17_state::u11_ca2_w)); + m_pia_u11->ca2_handler().set_output("led0"); m_pia_u11->cb2_handler().set(FUNC(by17_state::u11_cb2_w)); - m_pia_u11->irqa_handler().set_inputline("maincpu", M6800_IRQ_LINE); - m_pia_u11->irqb_handler().set_inputline("maincpu", M6800_IRQ_LINE); + m_pia_u11->irqa_handler().set_inputline(m_maincpu, M6800_IRQ_LINE); + m_pia_u11->irqb_handler().set_inputline(m_maincpu, M6800_IRQ_LINE); TIMER(config, "timer_d_freq").configure_periodic(FUNC(by17_state::u11_timer), attotime::from_hz(317)); // 555 timer TIMER(config, m_display_refresh_timer).configure_generic(FUNC(by17_state::timer_d_pulse)); // 555 Active pulse length } @@ -1149,6 +1148,8 @@ ROM_END / Stellar Airship / Geiger-Automatenbau GMBH, of Germany (1981) /---------------------------------------------------------------*/ +} // anonymous namespace + GAME( 1976, bowarrow, 0, by17, by17, by17_state, init_by17, ROT0, "Bally", "Bow & Arrow (Prototype, rev. 23)", MACHINE_IS_SKELETON_MECHANICAL) GAME( 1976, bowarrowa, bowarrow, by17, by17, by17_state, init_by17, ROT0, "Bally", "Bow & Arrow (Prototype, rev. 22)", MACHINE_IS_SKELETON_MECHANICAL) diff --git a/src/mame/drivers/by35.cpp b/src/mame/drivers/by35.cpp index 70d15834ce1..ca03a9bbf78 100644 --- a/src/mame/drivers/by35.cpp +++ b/src/mame/drivers/by35.cpp @@ -82,6 +82,8 @@ ToDo: #include "by35_playboy.lh" +namespace { + class by35_state : public genpin_class { public: @@ -157,7 +159,6 @@ protected: DECLARE_WRITE_LINE_MEMBER(u10_cb2_w); DECLARE_READ_LINE_MEMBER(u11_ca1_r); DECLARE_READ_LINE_MEMBER(u11_cb1_r); - DECLARE_WRITE_LINE_MEMBER(u11_ca2_w); DECLARE_WRITE_LINE_MEMBER(u11_cb2_w); virtual void machine_start() override; virtual void machine_reset() override; @@ -1066,11 +1067,6 @@ WRITE_LINE_MEMBER( by35_state::u10_cb2_w ) m_u10_cb2 = state; } -WRITE_LINE_MEMBER( by35_state::u11_ca2_w ) -{ - output().set_value("led0", state); -} - READ_LINE_MEMBER( by35_state::u11_ca1_r ) { return m_u11_ca1; @@ -1473,8 +1469,8 @@ void by35_state::by35(machine_config &config) m_pia_u10->readcb1_handler().set(FUNC(by35_state::u10_cb1_r)); m_pia_u10->ca2_handler().set(FUNC(by35_state::u10_ca2_w)); m_pia_u10->cb2_handler().set(FUNC(by35_state::u10_cb2_w)); - m_pia_u10->irqa_handler().set_inputline("maincpu", M6800_IRQ_LINE); - m_pia_u10->irqb_handler().set_inputline("maincpu", M6800_IRQ_LINE); + m_pia_u10->irqa_handler().set_inputline(m_maincpu, M6800_IRQ_LINE); + m_pia_u10->irqb_handler().set_inputline(m_maincpu, M6800_IRQ_LINE); TIMER(config, "timer_z_freq").configure_periodic(FUNC(by35_state::timer_z_freq), attotime::from_hz(100)); // Mains Line Frequency * 2 TIMER(config, m_zero_crossing_active_timer).configure_generic(FUNC(by35_state::timer_z_pulse)); // Active pulse length from Zero Crossing detector @@ -1484,10 +1480,10 @@ void by35_state::by35(machine_config &config) m_pia_u11->writepb_handler().set(FUNC(by35_state::u11_b_w)); m_pia_u11->readca1_handler().set(FUNC(by35_state::u11_ca1_r)); m_pia_u11->readcb1_handler().set(FUNC(by35_state::u11_cb1_r)); - m_pia_u11->ca2_handler().set(FUNC(by35_state::u11_ca2_w)); + m_pia_u11->ca2_handler().set_output("led0"); m_pia_u11->cb2_handler().set(FUNC(by35_state::u11_cb2_w)); - m_pia_u11->irqa_handler().set_inputline("maincpu", M6800_IRQ_LINE); - m_pia_u11->irqb_handler().set_inputline("maincpu", M6800_IRQ_LINE); + m_pia_u11->irqa_handler().set_inputline(m_maincpu, M6800_IRQ_LINE); + m_pia_u11->irqb_handler().set_inputline(m_maincpu, M6800_IRQ_LINE); TIMER(config, "timer_d_freq").configure_periodic(FUNC(by35_state::u11_timer), attotime::from_hz(317)); // 555 timer TIMER(config, m_display_refresh_timer).configure_generic(FUNC(by35_state::timer_d_pulse)); // 555 Active pulse length } @@ -2790,6 +2786,9 @@ ROM_START(suprbowl) ROM_LOAD("suprbowl.snd", 0xf000, 0x1000, CRC(97fc0f7a) SHA1(595aa080a6d2c1ab7e718974c4d01e846e142cc1)) ROM_END +} // anonymous namespace + + // AS-2888 sound GAME( 1979, sst, 0, as2888, by35, by35_state, init_by35_6, ROT0, "Bally", "Supersonic", MACHINE_MECHANICAL | MACHINE_NOT_WORKING) GAMEL(1978, playboy, 0, as2888, playboy, by35_state, init_by35_6, ROT0, "Bally", "Playboy", MACHINE_MECHANICAL | MACHINE_NOT_WORKING, layout_by35_playboy) diff --git a/src/mame/drivers/by6803.cpp b/src/mame/drivers/by6803.cpp index 5cea351558d..f79ffe5e45d 100644 --- a/src/mame/drivers/by6803.cpp +++ b/src/mame/drivers/by6803.cpp @@ -21,15 +21,19 @@ ToDo: #include "emu.h" +//#include "audio/midway.h" #include "machine/genpin.h" + #include "cpu/m6800/m6801.h" //#include "cpu/m6809/m6809.h" #include "machine/6821pia.h" #include "machine/timer.h" -//#include "audio/midway.h" + //#include "by6803.lh" +namespace { + class by6803_state : public genpin_class { public: @@ -39,12 +43,9 @@ public: , m_pia0(*this, "pia0") , m_pia1(*this, "pia1") , m_io_test(*this, "TEST") - , m_io_x0(*this, "X0") - , m_io_x1(*this, "X1") - , m_io_x2(*this, "X2") - , m_io_x3(*this, "X3") - , m_io_x4(*this, "X4") + , m_io_x(*this, "X%u", 0U) , m_digits(*this, "digit%u", 0U) + , m_leds(*this, "led%u", 0U) { } void init_by6803(); @@ -53,6 +54,10 @@ public: DECLARE_INPUT_CHANGED_MEMBER(activity_test); DECLARE_INPUT_CHANGED_MEMBER(self_test); +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + private: uint8_t port1_r(); void port1_w(uint8_t data); @@ -81,18 +86,13 @@ private: uint8_t m_port1, m_port2; //uint8_t m_digit; uint8_t m_segment; - virtual void machine_reset() override; - virtual void machine_start() override { m_digits.resolve(); } required_device m_maincpu; required_device m_pia0; required_device m_pia1; required_ioport m_io_test; - required_ioport m_io_x0; - required_ioport m_io_x1; - required_ioport m_io_x2; - required_ioport m_io_x3; - required_ioport m_io_x4; + required_ioport_array<5> m_io_x; output_finder<40> m_digits; + output_finder<1> m_leds; }; @@ -193,7 +193,7 @@ uint8_t by6803_state::port2_r() void by6803_state::port2_w(uint8_t data) { m_port2 = data; - output().set_value("led0", BIT(data, 2)); // P22 drives LED + m_leds[0] = BIT(data, 2); // P22 drives LED } // display latch strobes; display blanking @@ -254,20 +254,9 @@ uint8_t by6803_state::pia0_b_r() { uint8_t data = 0; - if (BIT(m_pia0_a, 0)) - data |= m_io_x0->read(); - - if (BIT(m_pia0_a, 1)) - data |= m_io_x1->read(); - - if (BIT(m_pia0_a, 2)) - data |= m_io_x2->read(); - - if (BIT(m_pia0_a, 3)) - data |= m_io_x3->read(); - - if (BIT(m_pia0_a, 4)) - data |= m_io_x4->read(); + for (unsigned i = 0; m_io_x.size() > i; ++i) + if (BIT(m_pia0_a, i)) + data |= m_io_x[i]->read(); return data; } @@ -342,6 +331,12 @@ void by6803_state::pia1_b_w(uint8_t data) } } +void by6803_state::machine_start() +{ + m_digits.resolve(); + m_leds.resolve(); +} + void by6803_state::machine_reset() { m_pia0_a = 0; @@ -750,6 +745,8 @@ ROM_START(trucksp2) ROM_RELOAD(0x20000 +0x8000, 0x8000) ROM_END +} // anonymous namespace + GAME( 1985, eballchp, 0, by6803, by6803, by6803_state, init_by6803, ROT0, "Bally", "Eight Ball Champ", MACHINE_IS_SKELETON_MECHANICAL) GAME( 1985, beatclck, 0, by6803, by6803, by6803_state, init_by6803, ROT0, "Bally", "Beat the Clock", MACHINE_IS_SKELETON_MECHANICAL) diff --git a/src/mame/drivers/exidy.cpp b/src/mame/drivers/exidy.cpp index 096b2ea215d..2060cb19ee1 100644 --- a/src/mame/drivers/exidy.cpp +++ b/src/mame/drivers/exidy.cpp @@ -149,25 +149,254 @@ Fax 1982 6502 FXL, FLA ***************************************************************************/ #include "emu.h" +#include "audio/exidy.h" + #include "cpu/m6502/m6502.h" #include "machine/6821pia.h" -#include "audio/exidy.h" -#include "includes/exidy.h" +#include "sound/dac.h" +#include "sound/samples.h" + +#include "emupal.h" +#include "screen.h" #include "speaker.h" +namespace { + +#define EXIDY_MASTER_CLOCK (XTAL(11'289'000)) +#define EXIDY_CPU_CLOCK (EXIDY_MASTER_CLOCK / 16) +#define EXIDY_PIXEL_CLOCK (EXIDY_MASTER_CLOCK / 2) +#define EXIDY_HTOTAL (0x150) +#define EXIDY_HBEND (0x000) +#define EXIDY_HBSTART (0x100) +#define EXIDY_HSEND (0x140) +#define EXIDY_HSSTART (0x120) +#define EXIDY_VTOTAL (0x118) +#define EXIDY_VBEND (0x000) +#define EXIDY_VBSTART (0x100) +#define EXIDY_VSEND (0x108) +#define EXIDY_VSSTART (0x100) + + +class exidy_state : public driver_device +{ +public: + enum + { + TIMER_COLLISION_IRQ + }; + + exidy_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_gfxdecode(*this, "gfxdecode"), + m_screen(*this, "screen"), + m_palette(*this, "palette"), + m_color_latch(*this, "color_latch"), + m_videoram(*this, "videoram"), + m_sprite1_xpos(*this, "sprite1_xpos"), + m_sprite1_ypos(*this, "sprite1_ypos"), + m_sprite2_xpos(*this, "sprite2_xpos"), + m_sprite2_ypos(*this, "sprite2_ypos"), + m_spriteno(*this, "spriteno"), + m_sprite_enable(*this, "sprite_enable"), + m_characterram(*this, "characterram") + { + } + + void venture(machine_config &config); + void mtrap(machine_config &config); + void pepper2(machine_config &config); + +protected: + required_device m_maincpu; + required_device m_gfxdecode; + required_device m_screen; + required_device m_palette; + required_shared_ptr m_color_latch; + + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + virtual void video_start() override; + + void base(machine_config &config); + + void exidy_video_config(uint8_t _collision_mask, uint8_t _collision_invert, int _is_2bpp); + + uint8_t exidy_interrupt_r(); + + void exidy_map(address_map &map); + +private: + required_shared_ptr m_videoram; + required_shared_ptr m_sprite1_xpos; + required_shared_ptr m_sprite1_ypos; + required_shared_ptr m_sprite2_xpos; + required_shared_ptr m_sprite2_ypos; + required_shared_ptr m_spriteno; + required_shared_ptr m_sprite_enable; + optional_shared_ptr m_characterram; + + uint8_t m_collision_mask; + uint8_t m_collision_invert; + int m_is_2bpp; + uint8_t m_int_condition; + bitmap_ind16 m_background_bitmap; + bitmap_ind16 m_motion_object_1_vid; + bitmap_ind16 m_motion_object_2_vid; + bitmap_ind16 m_motion_object_2_clip; + + void mtrap_ocl_w(uint8_t data); + + uint32_t screen_update_exidy(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + INTERRUPT_GEN_MEMBER(exidy_vblank_interrupt); + + void latch_condition(int collision); + void set_1_color(int index, int which); + void set_colors(); + void draw_background(); + int sprite_1_enabled(); + void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect); + void check_collision(); + + void venture_map(address_map &map); + void mtrap_map(address_map &map); + void pepper2_map(address_map &map); +}; + + +class spectar_state : public exidy_state +{ +public: + spectar_state(const machine_config &mconfig, device_type type, const char *tag) : + exidy_state(mconfig, type, tag), + m_dac(*this, "dac"), + m_samples(*this, "samples") + { + } + + void sidetrac(machine_config &config); + void spectar(machine_config &config); + void rallys(machine_config &config); + void phantoma(machine_config &config); + + void init_sidetrac(); + void init_spectar(); + +protected: + virtual void machine_start() override; + + void set_max_freq(int freq) { m_max_freq = freq; } + + void spectar_audio_1_w(uint8_t data); + void spectar_audio_2_w(uint8_t data); + + void adjust_sample(uint8_t freq); + bool RISING_EDGE(uint8_t data, uint8_t bit) const { return (data & bit) && !(m_port_1_last & bit); } + bool FALLING_EDGE(uint8_t data, uint8_t bit) const { return !(data & bit) && (m_port_1_last & bit); } + +private: + required_device m_dac; + required_device m_samples; + + // Targ and Spectar samples + int m_max_freq; + uint8_t m_port_1_last; + uint8_t m_tone_freq; + uint8_t m_tone_active; + + void sidetrac_map(address_map &map); + void spectar_map(address_map &map); + void rallys_map(address_map &map); + void phantoma_map(address_map &map); +}; + + +class targ_state : public spectar_state +{ +public: + targ_state(const machine_config &mconfig, device_type type, const char *tag) : + spectar_state(mconfig, type, tag), + m_sound_prom(*this, "targ") + { + } + + void targ(machine_config &config); + + void init_targ(); + +protected: + virtual void machine_start() override; + + void targ_audio_1_w(uint8_t data); + void targ_audio_2_w(uint8_t data); + +private: + required_region_ptr m_sound_prom; + + uint8_t m_port_2_last; + uint8_t m_tone_pointer; + + void targ_map(address_map &map); +}; + + +class teetert_state : public exidy_state +{ +public: + teetert_state(const machine_config &mconfig, device_type type, const char *tag) : + exidy_state(mconfig, type, tag), + m_dial(*this, "DIAL") + { + } + + void teetert(machine_config &config); + + DECLARE_CUSTOM_INPUT_MEMBER(teetert_input_r); + +protected: + virtual void machine_start() override; + +private: + required_ioport m_dial; + uint8_t m_last_dial; +}; + + +class fax_state : public exidy_state +{ +public: + fax_state(const machine_config &mconfig, device_type type, const char *tag) : + exidy_state(mconfig, type, tag), + m_rom_bank(*this, "bank1") + { + } + + void fax(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + required_memory_bank m_rom_bank; + + void fax_bank_select_w(uint8_t data); + + void fax_map(address_map &map); +}; + + /************************************* * * Special Teeter Torture input * *************************************/ -CUSTOM_INPUT_MEMBER(exidy_state::teetert_input_r) +CUSTOM_INPUT_MEMBER(teetert_state::teetert_input_r) { - uint8_t dial = ioport("DIAL")->read(); - int result = 0; + uint8_t dial = m_dial->read(); - result = (dial != m_last_dial) << 4; + int result = (dial != m_last_dial) << 4; if (result != 0) { if (((dial - m_last_dial) & 0xff) < 0x80) @@ -190,9 +419,9 @@ CUSTOM_INPUT_MEMBER(exidy_state::teetert_input_r) * *************************************/ -void exidy_state::fax_bank_select_w(uint8_t data) +void fax_state::fax_bank_select_w(uint8_t data) { - membank("bank1")->set_entry(data & 0x1f); + m_rom_bank->set_entry(data & 0x1f); if ((data & 0x1f) > 0x17) logerror("Banking to unpopulated ROM bank %02X!\n", data & 0x1f); @@ -231,40 +460,40 @@ void exidy_state::exidy_map(address_map &map) } -void exidy_state::sidetrac_map(address_map &map) +void spectar_state::sidetrac_map(address_map &map) { exidy_map(map); map(0x0800, 0x3fff).rom(); map(0x4800, 0x4fff).rom(); - map(0x5200, 0x5200).w(FUNC(exidy_state::targ_audio_1_w)); - map(0x5201, 0x5201).w(FUNC(exidy_state::spectar_audio_2_w)); + map(0x5200, 0x5200).w(FUNC(spectar_state::spectar_audio_1_w)); + map(0x5201, 0x5201).w(FUNC(spectar_state::spectar_audio_2_w)); map(0xff00, 0xffff).rom().region("maincpu", 0x3f00); } -void exidy_state::targ_map(address_map &map) +void targ_state::targ_map(address_map &map) { exidy_map(map); map(0x0800, 0x3fff).rom(); map(0x4800, 0x4fff).ram().share("characterram"); - map(0x5200, 0x5200).w(FUNC(exidy_state::targ_audio_1_w)); - map(0x5201, 0x5201).w(FUNC(exidy_state::targ_audio_2_w)); + map(0x5200, 0x5200).w(FUNC(targ_state::targ_audio_1_w)); + map(0x5201, 0x5201).w(FUNC(targ_state::targ_audio_2_w)); map(0xff00, 0xffff).rom().region("maincpu", 0x3f00); } -void exidy_state::spectar_map(address_map &map) +void spectar_state::spectar_map(address_map &map) { exidy_map(map); map(0x0800, 0x3fff).rom(); map(0x4800, 0x4fff).ram().share("characterram"); - map(0x5200, 0x5200).w(FUNC(exidy_state::targ_audio_1_w)); - map(0x5201, 0x5201).w(FUNC(exidy_state::spectar_audio_2_w)); + map(0x5200, 0x5200).w(FUNC(spectar_state::spectar_audio_1_w)); + map(0x5201, 0x5201).w(FUNC(spectar_state::spectar_audio_2_w)); map(0xff00, 0xffff).rom().region("maincpu", 0x3f00); } -void exidy_state::rallys_map(address_map &map) +void spectar_state::rallys_map(address_map &map) { map(0x0000, 0x03ff).ram(); map(0x0800, 0x3fff).rom(); @@ -276,9 +505,9 @@ void exidy_state::rallys_map(address_map &map) map(0x5100, 0x5100).mirror(0x00fc).writeonly().share("spriteno"); map(0x5101, 0x5101).mirror(0x00fc).portr("IN0"); map(0x5101, 0x5101).mirror(0x00fc).writeonly().share("sprite_enable"); - map(0x5103, 0x5103).mirror(0x00fc).r(FUNC(exidy_state::exidy_interrupt_r)); - map(0x5200, 0x5200).w(FUNC(exidy_state::targ_audio_1_w)); - map(0x5201, 0x5201).w(FUNC(exidy_state::spectar_audio_2_w)); + map(0x5103, 0x5103).mirror(0x00fc).r(FUNC(spectar_state::exidy_interrupt_r)); + map(0x5200, 0x5200).w(FUNC(spectar_state::spectar_audio_1_w)); + map(0x5201, 0x5201).w(FUNC(spectar_state::spectar_audio_2_w)); map(0x5210, 0x5212).writeonly().share("color_latch"); map(0x5213, 0x5213).portr("IN2"); map(0x5300, 0x5300).writeonly().share("sprite2_xpos"); @@ -287,6 +516,13 @@ void exidy_state::rallys_map(address_map &map) } +void spectar_state::phantoma_map(address_map &map) +{ + rallys_map(map); + map(0xf800, 0xffff).rom().region("maincpu", 0xf800); // the ROM is actually mapped high +} + + void exidy_state::venture_map(address_map &map) { exidy_map(map); @@ -311,14 +547,14 @@ void exidy_state::mtrap_map(address_map &map) map(0x5101, 0x5101).w(FUNC(exidy_state::mtrap_ocl_w)); } -void exidy_state::fax_map(address_map &map) +void fax_state::fax_map(address_map &map) { exidy_map(map); map(0x0400, 0x07ff).ram(); map(0x1a00, 0x1a00).portr("IN4"); map(0x1c00, 0x1c00).portr("IN3"); - map(0x2000, 0x2000).w(FUNC(exidy_state::fax_bank_select_w)); - map(0x2000, 0x3fff).bankr("bank1"); + map(0x2000, 0x2000).w(FUNC(fax_state::fax_bank_select_w)); + map(0x2000, 0x3fff).bankr(m_rom_bank); map(0x5200, 0x520f).rw("pia", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); map(0x5213, 0x5217).nopw(); /* empty control lines on color/sound board */ map(0x6000, 0x6fff).ram().share("characterram"); @@ -639,7 +875,7 @@ static INPUT_PORTS_START( teetert ) PORT_START("IN0") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 ) - PORT_BIT( 0x44, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(exidy_state, teetert_input_r) + PORT_BIT( 0x44, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(teetert_state, teetert_input_r) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) @@ -822,17 +1058,416 @@ GFXDECODE_END +/************************************* + * + * Video configuration + * + *************************************/ + +void exidy_state::exidy_video_config(uint8_t _collision_mask, uint8_t _collision_invert, int _is_2bpp) +{ + m_collision_mask = _collision_mask; + m_collision_invert = _collision_invert; + m_is_2bpp = _is_2bpp; +} + + + +/************************************* + * + * Video startup + * + *************************************/ + +void exidy_state::video_start() +{ + m_screen->register_screen_bitmap(m_background_bitmap); + m_motion_object_1_vid.allocate(16, 16); + m_motion_object_2_vid.allocate(16, 16); + m_motion_object_2_clip.allocate(16, 16); + + save_item(NAME(m_int_condition)); + save_item(NAME(m_background_bitmap)); + save_item(NAME(m_motion_object_1_vid)); + save_item(NAME(m_motion_object_2_vid)); + save_item(NAME(m_motion_object_2_clip)); +} + + + +/************************************* + * + * Interrupt generation + * + *************************************/ + +inline void exidy_state::latch_condition(int collision) +{ + collision ^= m_collision_invert; + m_int_condition = (ioport("INTSOURCE")->read() & ~0x1c) | (collision & m_collision_mask); +} + + +INTERRUPT_GEN_MEMBER(exidy_state::exidy_vblank_interrupt) +{ + /* latch the current condition */ + latch_condition(0); + m_int_condition &= ~0x80; + + /* set the IRQ line */ + device.execute().set_input_line(0, ASSERT_LINE); +} + + + +uint8_t exidy_state::exidy_interrupt_r() +{ + /* clear any interrupts */ + m_maincpu->set_input_line(0, CLEAR_LINE); + + /* return the latched condition */ + return m_int_condition; +} + + + +/************************************* + * + * Palette handling + * + *************************************/ + +inline void exidy_state::set_1_color(int index, int which) +{ + m_palette->set_pen_color(index, + pal1bit(m_color_latch[2] >> which), + pal1bit(m_color_latch[1] >> which), + pal1bit(m_color_latch[0] >> which)); +} + +void exidy_state::set_colors() +{ + /* motion object 1 */ + set_1_color(0, 0); + set_1_color(1, 7); + + /* motion object 2 */ + set_1_color(2, 0); + set_1_color(3, 6); + + /* characters */ + set_1_color(4, 4); + set_1_color(5, 3); + set_1_color(6, 2); + set_1_color(7, 1); +} + + + +/************************************* + * + * Background update + * + *************************************/ + +void exidy_state::draw_background() +{ + const uint8_t *const cram = m_characterram ? &m_characterram[0] : memregion("maincpu")->base() + 0x4800; + + pen_t off_pen = 0; + + for (offs_t offs = 0; offs < 0x400; offs++) + { + uint8_t y = offs >> 5 << 3; + uint8_t const code = m_videoram[offs]; + + pen_t on_pen_1, on_pen_2; + if (m_is_2bpp) + { + on_pen_1 = 4 + ((code >> 6) & 0x02); + on_pen_2 = 5 + ((code >> 6) & 0x02); + } + else + { + on_pen_1 = 4 + ((code >> 6) & 0x03); + on_pen_2 = off_pen; /* unused */ + } + + for (uint8_t cy = 0; cy < 8; cy++) + { + uint8_t x = offs << 3; + + if (m_is_2bpp) + { + uint8_t data1 = cram[0x000 | (code << 3) | cy]; + uint8_t data2 = cram[0x800 | (code << 3) | cy]; + + for (int i = 0; i < 8; i++) + { + if (data1 & 0x80) + m_background_bitmap.pix(y, x) = (data2 & 0x80) ? on_pen_2 : on_pen_1; + else + m_background_bitmap.pix(y, x) = off_pen; + + x++; + data1 <<= 1; + data2 <<= 1; + } + } + else // 1bpp + { + uint8_t data = cram[(code << 3) | cy]; + + for (int i = 0; i < 8; i++) + { + m_background_bitmap.pix(y, x) = (data & 0x80) ? on_pen_1 : off_pen; + + x++; + data <<= 1; + } + } + + y++; + } + } +} + + + +/************************************* + * + * Sprite hardware + * + *************************************/ + +inline int exidy_state::sprite_1_enabled() +{ + /* if the collision_mask is 0x00, then we are on old hardware that always has */ + /* sprite 1 enabled regardless */ + return (!(*m_sprite_enable & 0x80) || (*m_sprite_enable & 0x10) || (m_collision_mask == 0x00)); +} + + +void exidy_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + /* draw sprite 2 first */ + int sprite_set_2 = ((*m_sprite_enable & 0x40) != 0); + + int sx = 236 - *m_sprite2_xpos - 4; + int sy = 244 - *m_sprite2_ypos - 4; + + m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, + ((*m_spriteno >> 4) & 0x0f) + 32 + 16 * sprite_set_2, 1, + 0, 0, sx, sy, 0); + + /* draw sprite 1 next */ + if (sprite_1_enabled()) + { + int sprite_set_1 = ((*m_sprite_enable & 0x20) != 0); + + sx = 236 - *m_sprite1_xpos - 4; + sy = 244 - *m_sprite1_ypos - 4; + + if (sy < 0) sy = 0; + + m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, + (*m_spriteno & 0x0f) + 16 * sprite_set_1, 0, + 0, 0, sx, sy, 0); + } + +} + + + +/************************************* + * + * Collision detection + * + *************************************/ + +/*************************************************************************** + + Exidy hardware checks for two types of collisions based on the video + signals. If the Motion Object 1 and Motion Object 2 signals are on at + the same time, an M1M2 collision bit gets set. If the Motion Object 1 + and Background Character signals are on at the same time, an M1CHAR + collision bit gets set. So effectively, there's a pixel-by-pixel + collision check comparing Motion Object 1 (the player) to the + background and to the other Motion Object (typically a bad guy). + +***************************************************************************/ + +void exidy_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (id) + { + case TIMER_COLLISION_IRQ: + /* latch the collision bits */ + latch_condition(param); + + /* set the IRQ line */ + m_maincpu->set_input_line(0, ASSERT_LINE); + + break; + default: + throw emu_fatalerror("Unknown id in exidy_state::device_timer"); + } +} + + +void exidy_state::check_collision() +{ + uint8_t sprite_set_1 = ((*m_sprite_enable & 0x20) != 0); + uint8_t sprite_set_2 = ((*m_sprite_enable & 0x40) != 0); + const rectangle clip(0, 15, 0, 15); + int org_1_x = 0, org_1_y = 0; + int org_2_x = 0, org_2_y = 0; + int count = 0; + + /* if there is nothing to detect, bail */ + if (m_collision_mask == 0) + return; + + /* draw sprite 1 */ + m_motion_object_1_vid.fill(0xff, clip); + if (sprite_1_enabled()) + { + org_1_x = 236 - *m_sprite1_xpos - 4; + org_1_y = 244 - *m_sprite1_ypos - 4; + m_gfxdecode->gfx(0)->transpen(m_motion_object_1_vid,clip, + (*m_spriteno & 0x0f) + 16 * sprite_set_1, 0, + 0, 0, 0, 0, 0); + } + + /* draw sprite 2 */ + m_motion_object_2_vid.fill(0xff, clip); + org_2_x = 236 - *m_sprite2_xpos - 4; + org_2_y = 244 - *m_sprite2_ypos - 4; + m_gfxdecode->gfx(0)->transpen(m_motion_object_2_vid,clip, + ((*m_spriteno >> 4) & 0x0f) + 32 + 16 * sprite_set_2, 0, + 0, 0, 0, 0, 0); + + /* draw sprite 2 clipped to sprite 1's location */ + m_motion_object_2_clip.fill(0xff, clip); + if (sprite_1_enabled()) + { + int sx = org_2_x - org_1_x; + int sy = org_2_y - org_1_y; + m_gfxdecode->gfx(0)->transpen(m_motion_object_2_clip,clip, + ((*m_spriteno >> 4) & 0x0f) + 32 + 16 * sprite_set_2, 0, + 0, 0, sx, sy, 0); + } + + /* scan for collisions */ + for (int sy = 0; sy < 16; sy++) + for (int sx = 0; sx < 16; sx++) + { + if (m_motion_object_1_vid.pix(sy, sx) != 0xff) + { + uint8_t current_collision_mask = 0; + + /* check for background collision (M1CHAR) */ + if (m_background_bitmap.pix(org_1_y + sy, org_1_x + sx) != 0) + current_collision_mask |= 0x04; + + /* check for motion object collision (M1M2) */ + if (m_motion_object_2_clip.pix(sy, sx) != 0xff) + current_collision_mask |= 0x10; + + /* if we got one, trigger an interrupt */ + if ((current_collision_mask & m_collision_mask) && (count++ < 128)) + timer_set(m_screen->time_until_pos(org_1_x + sx, org_1_y + sy), TIMER_COLLISION_IRQ, current_collision_mask); + } + + if (m_motion_object_2_vid.pix(sy, sx) != 0xff) + { + /* check for background collision (M2CHAR) */ + if (m_background_bitmap.pix(org_2_y + sy, org_2_x + sx) != 0) + if ((m_collision_mask & 0x08) && (count++ < 128)) + timer_set(m_screen->time_until_pos(org_2_x + sx, org_2_y + sy), TIMER_COLLISION_IRQ, 0x08); + } + } +} + + + +/************************************* + * + * Standard screen refresh callback + * + *************************************/ + +uint32_t exidy_state::screen_update_exidy(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + /* refresh the colors from the palette (static or dynamic) */ + set_colors(); + + /* update the background and draw it */ + draw_background(); + copybitmap(bitmap, m_background_bitmap, 0, 0, 0, 0, cliprect); + + /* draw the sprites */ + draw_sprites(bitmap, cliprect); + + /* check for collision, this will set the appropriate bits in collision_mask */ + check_collision(); + + return 0; +} + + + /************************************* * * Machine init * *************************************/ -MACHINE_START_MEMBER(exidy_state,teetert) +void spectar_state::machine_start() { + exidy_state::machine_start(); + + m_tone_freq = 0; + m_tone_active = 0; + + /* start_raw can't be called here: chan.source will be set by + samples_device::device_start and then nulled out by samples_device::device_reset + at the soft_reset stage of init_machine() and will never be set again. + Thus, I've moved it to exidy_state::adjust_sample() were it will be set after + machine initialization. */ + //m_samples->set_volume(3, 0); + //m_samples->start_raw(3, sine_wave, 32, 1000, true); + + save_item(NAME(m_port_1_last)); + save_item(NAME(m_tone_freq)); + save_item(NAME(m_tone_active)); +} + +void targ_state::machine_start() +{ + spectar_state::machine_start(); + + m_tone_pointer = 0; + + save_item(NAME(m_port_2_last)); + save_item(NAME(m_tone_pointer)); +} + +void teetert_state::machine_start() +{ + exidy_state::machine_start(); + save_item(NAME(m_last_dial)); } +void fax_state::machine_start() +{ + exidy_state::machine_start(); + + m_rom_bank->configure_entries(0, 32, memregion("maincpu")->base() + 0x10000, 0x2000); +} + + /************************************* * * Machine drivers @@ -841,11 +1476,11 @@ MACHINE_START_MEMBER(exidy_state,teetert) void exidy_state::base(machine_config &config) { - /* basic machine hardware */ + // basic machine hardware M6502(config, m_maincpu, EXIDY_CPU_CLOCK); m_maincpu->set_vblank_int("screen", FUNC(exidy_state::exidy_vblank_interrupt)); - /* video hardware */ + // video hardware GFXDECODE(config, m_gfxdecode, m_palette, gfx_exidy); PALETTE(config, m_palette).set_entries(8); @@ -857,48 +1492,77 @@ void exidy_state::base(machine_config &config) } -void exidy_state::sidetrac(machine_config &config) +void spectar_state::sidetrac(machine_config &config) { + static const char *const sample_names[] = + { + "*targ", + "expl", + "shot", + "sexpl", + "spslow", + "spfast", + nullptr + }; + base(config); - /* basic machine hardware */ - m_maincpu->set_addrmap(AS_PROGRAM, &exidy_state::sidetrac_map); + // basic machine hardware + m_maincpu->set_addrmap(AS_PROGRAM, &spectar_state::sidetrac_map); + + // video hardware + exidy_video_config(0x00, 0x00, false); + + // audio hardware + set_max_freq(525'000); + + SPEAKER(config, "speaker").front_center(); + + SAMPLES(config, m_samples); + m_samples->set_channels(4); + m_samples->set_samples_names(sample_names); + m_samples->add_route(ALL_OUTPUTS, "speaker", 0.25); - /* audio hardware */ - spectar_audio(config); + DAC_1BIT(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.99); } -void exidy_state::targ(machine_config &config) +void targ_state::targ(machine_config &config) { - base(config); + sidetrac(config); - /* basic machine hardware */ - m_maincpu->set_addrmap(AS_PROGRAM, &exidy_state::targ_map); + // basic machine hardware + m_maincpu->set_addrmap(AS_PROGRAM, &targ_state::targ_map); - /* audio hardware */ - targ_audio(config); + // audio hardware + set_max_freq(125'000); } -void exidy_state::spectar(machine_config &config) +void spectar_state::spectar(machine_config &config) { - base(config); + sidetrac(config); - /* basic machine hardware */ - m_maincpu->set_addrmap(AS_PROGRAM, &exidy_state::spectar_map); + // basic machine hardware + m_maincpu->set_addrmap(AS_PROGRAM, &spectar_state::spectar_map); +} - /* audio hardware */ - spectar_audio(config); + +void spectar_state::rallys(machine_config &config) +{ + sidetrac(config); + + // basic machine hardware + m_maincpu->set_addrmap(AS_PROGRAM, &spectar_state::rallys_map); } -void exidy_state::rallys(machine_config &config) +void spectar_state::phantoma(machine_config &config) { - spectar(config); + sidetrac(config); - /* basic machine hardware */ - m_maincpu->set_addrmap(AS_PROGRAM, &exidy_state::rallys_map); + // basic machine hardware + m_maincpu->set_addrmap(AS_PROGRAM, &spectar_state::phantoma_map); } @@ -906,12 +1570,15 @@ void exidy_state::venture(machine_config &config) { base(config); - /* basic machine hardware */ + // basic machine hardware m_maincpu->set_addrmap(AS_PROGRAM, &exidy_state::venture_map); config.set_maximum_quantum(attotime::from_hz(600)); - /* audio hardware */ + // video hardware + exidy_video_config(0x04, 0x04, false); + + // audio hardware pia6821_device &pia(PIA6821(config, "pia", 0)); pia.writepa_handler().set("soundbd", FUNC(venture_sound_device::pb_w)); pia.writepb_handler().set("soundbd", FUNC(venture_sound_device::pa_w)); @@ -926,14 +1593,15 @@ void exidy_state::venture(machine_config &config) } -void exidy_state::teetert(machine_config &config) +void teetert_state::teetert(machine_config &config) { venture(config); - /* basic machine hardware */ - m_maincpu->set_periodic_int(FUNC(exidy_state::nmi_line_pulse), attotime::from_hz(10*60)); + // basic machine hardware + m_maincpu->set_periodic_int(FUNC(teetert_state::nmi_line_pulse), attotime::from_hz(10*60)); - MCFG_MACHINE_START_OVERRIDE(exidy_state, teetert ) + // video hardware + exidy_video_config(0x0c, 0x0c, false); } @@ -941,12 +1609,15 @@ void exidy_state::mtrap(machine_config &config) { base(config); - /* basic machine hardware */ + // basic machine hardware m_maincpu->set_addrmap(AS_PROGRAM, &exidy_state::mtrap_map); config.set_maximum_quantum(attotime::from_hz(1920)); - /* audio hardware */ + // video hardware + exidy_video_config(0x14, 0x00, false); + + // audio hardware pia6821_device &pia(PIA6821(config, "pia", 0)); pia.writepa_handler().set("soundbd", FUNC(venture_sound_device::pb_w)); pia.writepb_handler().set("soundbd", FUNC(venture_sound_device::pa_w)); @@ -965,17 +1636,23 @@ void exidy_state::pepper2(machine_config &config) { venture(config); - /* basic machine hardware */ + // basic machine hardware m_maincpu->set_addrmap(AS_PROGRAM, &exidy_state::pepper2_map); + + // video hardware + exidy_video_config(0x14, 0x04, true); } -void exidy_state::fax(machine_config &config) +void fax_state::fax(machine_config &config) { pepper2(config); - /* basic machine hardware */ - m_maincpu->set_addrmap(AS_PROGRAM, &exidy_state::fax_map); + // basic machine hardware + m_maincpu->set_addrmap(AS_PROGRAM, &fax_state::fax_map); + + // video hardware + exidy_video_config(0x04, 0x04, true); } /************************************************************************* @@ -991,22 +1668,14 @@ void exidy_state::fax(machine_config &config) 3 = Tone generator */ -#define SPECTAR_MAXFREQ 525000 -#define TARG_MAXFREQ 125000 - static const int16_t sine_wave[32] = { - 0x0f0f, 0x0f0f, 0x0f0f, 0x0606, 0x0606, 0x0909, 0x0909, 0x0606, 0x0606, 0x0909, 0x0606, 0x0d0d, 0x0f0f, 0x0f0f, 0x0d0d, 0x0000, + 0x0f0f, 0x0f0f, 0x0f0f, 0x0606, 0x0606, 0x0909, 0x0909, 0x0606, 0x0606, 0x0909, 0x0606, 0x0d0d, 0x0f0f, 0x0f0f, 0x0d0d, 0x0000, -0x191a, -0x2122, -0x1e1f, -0x191a, -0x1314, -0x191a, -0x1819, -0x1819, -0x1819, -0x1314, -0x1314, -0x1314, -0x1819, -0x1e1f, -0x1e1f, -0x1819 }; -/* some macros to make detecting bit changes easier */ -#define RISING_EDGE(bit) ( (data & bit) && !(m_port_1_last & bit)) -#define FALLING_EDGE(bit) (!(data & bit) && (m_port_1_last & bit)) - - -void exidy_state::adjust_sample(uint8_t freq) +void spectar_state::adjust_sample(uint8_t freq) { m_tone_freq = freq; @@ -1026,18 +1695,20 @@ void exidy_state::adjust_sample(uint8_t freq) } -void exidy_state::targ_audio_1_w(uint8_t data) +void spectar_state::spectar_audio_1_w(uint8_t data) { - /* CPU music */ + // CPU music if (BIT(m_port_1_last ^ data, 0)) m_dac->write(BIT(data, 0)); - /* shot */ - if (FALLING_EDGE(0x02) && !m_samples->playing(0)) m_samples->start(0,1); - if (RISING_EDGE(0x02)) m_samples->start(0,1); + // shot + if (FALLING_EDGE(data, 0x02) && !m_samples->playing(0)) + m_samples->start(0,1); + if (RISING_EDGE(data, 0x02)) + m_samples->start(0,1); - /* crash */ - if (RISING_EDGE(0x20)) + // crash + if (RISING_EDGE(data, 0x20)) { if (data & 0x40) m_samples->start(1,0); @@ -1045,7 +1716,7 @@ void exidy_state::targ_audio_1_w(uint8_t data) m_samples->start(1,2); } - /* Sspec */ + // Sspec if (data & 0x10) m_samples->stop(2); else @@ -1059,122 +1730,49 @@ void exidy_state::targ_audio_1_w(uint8_t data) } } - /* Game (tone generator enable) */ - if (FALLING_EDGE(0x80)) + // Game (tone generator enable) + if (FALLING_EDGE(data, 0x80)) { - m_tone_pointer = 0; m_tone_active = 0; adjust_sample(m_tone_freq); } - if (RISING_EDGE(0x80)) - m_tone_active=1; + if (RISING_EDGE(data, 0x80)) + m_tone_active = 1; m_port_1_last = data; } -void exidy_state::targ_audio_2_w(uint8_t data) -{ - if ((data & 0x01) && !(m_port_2_last & 0x01)) - { - uint8_t *prom = memregion("targ")->base(); - - m_tone_pointer = (m_tone_pointer + 1) & 0x0f; - - adjust_sample(prom[((data & 0x02) << 3) | m_tone_pointer]); - } - - m_port_2_last = data; -} - - -void exidy_state::spectar_audio_2_w(uint8_t data) +void spectar_state::spectar_audio_2_w(uint8_t data) { adjust_sample(data); } -static const char *const sample_names[] = -{ - "*targ", - "expl", - "shot", - "sexpl", - "spslow", - "spfast", - nullptr -}; - - - -void exidy_state::common_audio_start(int freq) -{ - m_max_freq = freq; - - m_tone_freq = 0; - m_tone_active = 0; - - /* start_raw can't be called here: chan.source will be set by - samples_device::device_start and then nulled out by samples_device::device_reset - at the soft_reset stage of init_machine() and will never be set again. - Thus, I've moved it to exidy_state::adjust_sample() were it will be set after - machine initialization. */ - //m_samples->set_volume(3, 0); - //m_samples->start_raw(3, sine_wave, 32, 1000, true); - - save_item(NAME(m_port_1_last)); - save_item(NAME(m_port_2_last)); - save_item(NAME(m_tone_freq)); - save_item(NAME(m_tone_active)); -} - - -SAMPLES_START_CB_MEMBER(exidy_state::spectar_audio_start) -{ - common_audio_start(SPECTAR_MAXFREQ); -} - - -SAMPLES_START_CB_MEMBER(exidy_state::targ_audio_start) +void targ_state::targ_audio_1_w(uint8_t data) { - common_audio_start(TARG_MAXFREQ); - - m_tone_pointer = 0; + if (FALLING_EDGE(data, 0x80)) + m_tone_pointer = 0; - save_item(NAME(m_tone_pointer)); + spectar_audio_1_w(data); } -void exidy_state::spectar_audio(machine_config &config) +void targ_state::targ_audio_2_w(uint8_t data) { - SPEAKER(config, "speaker").front_center(); - - SAMPLES(config, m_samples); - m_samples->set_channels(4); - m_samples->set_samples_names(sample_names); - m_samples->set_samples_start_callback(FUNC(exidy_state::spectar_audio_start)); - m_samples->add_route(ALL_OUTPUTS, "speaker", 0.25); - - DAC_1BIT(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.99); -} - -void exidy_state::targ_audio(machine_config &config) -{ - SPEAKER(config, "speaker").front_center(); + if ((data & 0x01) && !(m_port_2_last & 0x01)) + { + m_tone_pointer = (m_tone_pointer + 1) & 0x0f; - SAMPLES(config, m_samples); - m_samples->set_channels(4); - m_samples->set_samples_names(sample_names); - m_samples->set_samples_start_callback(FUNC(exidy_state::targ_audio_start)); - m_samples->add_route(ALL_OUTPUTS, "speaker", 0.25); + adjust_sample(m_sound_prom[((data & 0x02) << 3) | m_tone_pointer]); + } - DAC_1BIT(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.99); + m_port_2_last = data; } - /************************************* * * ROM definitions @@ -1878,94 +2476,33 @@ ROM_END * *************************************/ -void exidy_state::init_sidetrac() +void spectar_state::init_sidetrac() { - exidy_video_config(0x00, 0x00, false); - - /* hard-coded palette controlled via 8x3 DIP switches on the board */ + // hard-coded palette controlled via 8x3 DIP switches on the board m_color_latch[2] = 0xf8; m_color_latch[1] = 0xdc; m_color_latch[0] = 0xb8; } -void exidy_state::init_targ() +void targ_state::init_targ() { - exidy_video_config(0x00, 0x00, false); - - /* hard-coded palette controlled via 8x3 DIP switches on the board */ + // hard-coded palette controlled via 8x3 DIP switches on the board m_color_latch[2] = 0x5c; m_color_latch[1] = 0xee; m_color_latch[0] = 0x6b; } -void exidy_state::init_spectar() -{ - exidy_video_config(0x00, 0x00, false); - - /* hard-coded palette controlled via 8x3 DIP switches on the board */ - m_color_latch[2] = 0x58; - m_color_latch[1] = 0xee; - m_color_latch[0] = 0x09; -} - -void exidy_state::init_rallys() -{ - exidy_video_config(0x00, 0x00, false); - - /* hard-coded palette controlled via 8x3 DIP switches on the board */ - m_color_latch[2] = 0x58; - m_color_latch[1] = 0xee; - m_color_latch[0] = 0x09; -} - -void exidy_state::init_phantoma() +void spectar_state::init_spectar() { - exidy_video_config(0x00, 0x00, false); - - /* hard-coded palette controlled via 8x3 DIP switches on the board */ + // hard-coded palette controlled via 8x3 DIP switches on the board m_color_latch[2] = 0x58; m_color_latch[1] = 0xee; m_color_latch[0] = 0x09; - - /* the ROM is actually mapped high */ - m_maincpu->space(AS_PROGRAM).install_rom(0xf800, 0xffff, memregion("maincpu")->base() + 0xf800); } - -void exidy_state::init_mtrap() -{ - exidy_video_config(0x14, 0x00, false); -} - - -void exidy_state::init_venture() -{ - exidy_video_config(0x04, 0x04, false); -} - - -void exidy_state::init_teetert() -{ - exidy_video_config(0x0c, 0x0c, false); -} - - -void exidy_state::init_pepper2() -{ - exidy_video_config(0x14, 0x04, true); -} - - -void exidy_state::init_fax() -{ - //address_space &space = m_maincpu->space(AS_PROGRAM); - - exidy_video_config(0x04, 0x04, true); - - membank("bank1")->configure_entries(0, 32, memregion("maincpu")->base() + 0x10000, 0x2000); -} +} // anonymous namespace @@ -1975,38 +2512,38 @@ void exidy_state::init_fax() * *************************************/ -GAME( 1979, sidetrac, 0, sidetrac, sidetrac, exidy_state, init_sidetrac, ROT0, "Exidy", "Side Trak", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // "Side Track" on title screen, but cabinet/flyers/documentation clearly indicates otherwise, "Side Trak" it is +GAME( 1979, sidetrac, 0, sidetrac, sidetrac, spectar_state, init_sidetrac, ROT0, "Exidy", "Side Trak", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // "Side Track" on title screen, but cabinet/flyers/documentation clearly indicates otherwise, "Side Trak" it is -GAME( 1980, targ, 0, targ, targ, exidy_state, init_targ, ROT0, "Exidy", "Targ", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1980, targc, targ, targ, targ, exidy_state, init_targ, ROT0, "Exidy", "Targ (cocktail?)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, targ, 0, targ, targ, targ_state, init_targ, ROT0, "Exidy", "Targ", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, targc, targ, targ, targ, targ_state, init_targ, ROT0, "Exidy", "Targ (cocktail?)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1980, spectar, 0, spectar, spectar, exidy_state, init_spectar, ROT0, "Exidy", "Spectar (revision 3)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1980, spectar1, spectar, spectar, spectar, exidy_state, init_spectar, ROT0, "Exidy", "Spectar (revision 1?)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, spectarrf, spectar, spectar, spectarrf, exidy_state, init_spectar, ROT0, "bootleg (Recreativos Franco)", "Spectar (revision 2, bootleg)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1980, rallys, spectar, rallys, rallys, exidy_state, init_rallys, ROT0, "bootleg (Novar)", "Rallys (bootleg of Spectar, set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1980, rallysa, spectar, rallys, rallys, exidy_state, init_rallys, ROT0, "bootleg (Musik Box Brescia)", "Rallys (bootleg of Spectar, set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1980, panzer, spectar, rallys, rallys, exidy_state, init_rallys, ROT0, "bootleg (Proel)", "Panzer (bootleg of Spectar)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1980, phantoma, spectar, rallys, phantoma, exidy_state, init_phantoma, ROT0, "bootleg (Jeutel)", "Phantomas (bootleg of Spectar)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1980, phantom, spectar, rallys, phantoma, exidy_state, init_phantoma, ROT0, "bootleg (Proel)", "Phantom (bootleg of Spectar)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, spectar, 0, spectar, spectar, spectar_state, init_spectar, ROT0, "Exidy", "Spectar (revision 3)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, spectar1, spectar, spectar, spectar, spectar_state, init_spectar, ROT0, "Exidy", "Spectar (revision 1?)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, spectarrf, spectar, spectar, spectarrf, spectar_state, init_spectar, ROT0, "bootleg (Recreativos Franco)", "Spectar (revision 2, bootleg)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, rallys, spectar, rallys, rallys, spectar_state, init_spectar, ROT0, "bootleg (Novar)", "Rallys (bootleg of Spectar, set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, rallysa, spectar, rallys, rallys, spectar_state, init_spectar, ROT0, "bootleg (Musik Box Brescia)", "Rallys (bootleg of Spectar, set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, panzer, spectar, rallys, rallys, spectar_state, init_spectar, ROT0, "bootleg (Proel)", "Panzer (bootleg of Spectar)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, phantoma, spectar, phantoma, phantoma, spectar_state, init_spectar, ROT0, "bootleg (Jeutel)", "Phantomas (bootleg of Spectar)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, phantom, spectar, phantoma, phantoma, spectar_state, init_spectar, ROT0, "bootleg (Proel)", "Phantom (bootleg of Spectar)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1981, mtrap, 0, mtrap, mtrap, exidy_state, init_mtrap, ROT0, "Exidy", "Mouse Trap (version 5)", MACHINE_SUPPORTS_SAVE ) -GAME( 1981, mtrap4, mtrap, mtrap, mtrap, exidy_state, init_mtrap, ROT0, "Exidy", "Mouse Trap (version 4)", MACHINE_SUPPORTS_SAVE ) -GAME( 1981, mtrap3, mtrap, mtrap, mtrap, exidy_state, init_mtrap, ROT0, "Exidy", "Mouse Trap (version 3)", MACHINE_SUPPORTS_SAVE ) -GAME( 1981, mtrap2, mtrap, mtrap, mtrap, exidy_state, init_mtrap, ROT0, "Exidy", "Mouse Trap (version 2)", MACHINE_SUPPORTS_SAVE ) -GAME( 1981, mtrapb, mtrap, mtrap, mtrap, exidy_state, init_mtrap, ROT0, "bootleg", "Mouse Trap (bootleg)", MACHINE_SUPPORTS_SAVE ) -GAME( 1981, mtrapb2, mtrap, mtrap, mtrap, exidy_state, init_mtrap, ROT0, "bootleg", "Mouse Trap (version 4, bootleg)", MACHINE_SUPPORTS_SAVE ) +GAME( 1981, mtrap, 0, mtrap, mtrap, exidy_state, empty_init, ROT0, "Exidy", "Mouse Trap (version 5)", MACHINE_SUPPORTS_SAVE ) +GAME( 1981, mtrap4, mtrap, mtrap, mtrap, exidy_state, empty_init, ROT0, "Exidy", "Mouse Trap (version 4)", MACHINE_SUPPORTS_SAVE ) +GAME( 1981, mtrap3, mtrap, mtrap, mtrap, exidy_state, empty_init, ROT0, "Exidy", "Mouse Trap (version 3)", MACHINE_SUPPORTS_SAVE ) +GAME( 1981, mtrap2, mtrap, mtrap, mtrap, exidy_state, empty_init, ROT0, "Exidy", "Mouse Trap (version 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1981, mtrapb, mtrap, mtrap, mtrap, exidy_state, empty_init, ROT0, "bootleg", "Mouse Trap (bootleg)", MACHINE_SUPPORTS_SAVE ) +GAME( 1981, mtrapb2, mtrap, mtrap, mtrap, exidy_state, empty_init, ROT0, "bootleg", "Mouse Trap (version 4, bootleg)", MACHINE_SUPPORTS_SAVE ) -GAME( 1981, venture, 0, venture, venture, exidy_state, init_venture, ROT0, "Exidy", "Venture (version 5 set 1)", MACHINE_SUPPORTS_SAVE ) -GAME( 1981, venture5a, venture, venture, venture, exidy_state, init_venture, ROT0, "Exidy", "Venture (version 5 set 2)", MACHINE_SUPPORTS_SAVE ) -GAME( 1981, venture4, venture, venture, venture, exidy_state, init_venture, ROT0, "Exidy", "Venture (version 4)", MACHINE_SUPPORTS_SAVE ) -GAME( 1981, venture5b, venture, venture, venture, exidy_state, init_venture, ROT0, "bootleg", "Venture (version 5 set 2, bootleg)", MACHINE_SUPPORTS_SAVE ) +GAME( 1981, venture, 0, venture, venture, exidy_state, empty_init, ROT0, "Exidy", "Venture (version 5 set 1)", MACHINE_SUPPORTS_SAVE ) +GAME( 1981, venture5a, venture, venture, venture, exidy_state, empty_init, ROT0, "Exidy", "Venture (version 5 set 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1981, venture4, venture, venture, venture, exidy_state, empty_init, ROT0, "Exidy", "Venture (version 4)", MACHINE_SUPPORTS_SAVE ) +GAME( 1981, venture5b, venture, venture, venture, exidy_state, empty_init, ROT0, "bootleg", "Venture (version 5 set 2, bootleg)", MACHINE_SUPPORTS_SAVE ) -GAME( 1982, teetert, 0, teetert, teetert, exidy_state, init_teetert, ROT0, "Exidy", "Teeter Torture (prototype)", MACHINE_SUPPORTS_SAVE ) +GAME( 1982, teetert, 0, teetert, teetert, teetert_state, empty_init, ROT0, "Exidy", "Teeter Torture (prototype)", MACHINE_SUPPORTS_SAVE ) -GAME( 1982, pepper2, 0, pepper2, pepper2, exidy_state, init_pepper2, ROT0, "Exidy", "Pepper II (version 8)", MACHINE_SUPPORTS_SAVE ) -GAME( 1982, pepper27, pepper2, pepper2, pepper2, exidy_state, init_pepper2, ROT0, "Exidy", "Pepper II (version 7)", MACHINE_SUPPORTS_SAVE ) +GAME( 1982, pepper2, 0, pepper2, pepper2, exidy_state, empty_init, ROT0, "Exidy", "Pepper II (version 8)", MACHINE_SUPPORTS_SAVE ) +GAME( 1982, pepper27, pepper2, pepper2, pepper2, exidy_state, empty_init, ROT0, "Exidy", "Pepper II (version 7)", MACHINE_SUPPORTS_SAVE ) -GAME( 1982, hardhat, 0, pepper2, pepper2, exidy_state, init_pepper2, ROT0, "Exidy", "Hard Hat", MACHINE_SUPPORTS_SAVE ) +GAME( 1982, hardhat, 0, pepper2, pepper2, exidy_state, empty_init, ROT0, "Exidy", "Hard Hat", MACHINE_SUPPORTS_SAVE ) -GAME( 1983, fax, 0, fax, fax, exidy_state, init_fax, ROT0, "Exidy", "FAX", MACHINE_SUPPORTS_SAVE ) -GAME( 1983, fax2, fax, fax, fax, exidy_state, init_fax, ROT0, "Exidy", "FAX 2", MACHINE_SUPPORTS_SAVE ) +GAME( 1983, fax, 0, fax, fax, fax_state, empty_init, ROT0, "Exidy", "FAX", MACHINE_SUPPORTS_SAVE ) +GAME( 1983, fax2, fax, fax, fax, fax_state, empty_init, ROT0, "Exidy", "FAX 2", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/f-32.cpp b/src/mame/drivers/f-32.cpp index e5be92fede8..e3849a5254d 100644 --- a/src/mame/drivers/f-32.cpp +++ b/src/mame/drivers/f-32.cpp @@ -108,7 +108,7 @@ public: fe132_state(mconfig, type, tag), m_nvram(*this, "nvram"), m_hopper(*this, "hopper"), - m_lamps(*this, "lamps%u", 0U) + m_lamps(*this, "lamp%u", 0U) { } void royalpk2(machine_config &config); diff --git a/src/mame/drivers/opwolf.cpp b/src/mame/drivers/opwolf.cpp index 371d84e1368..041482976aa 100644 --- a/src/mame/drivers/opwolf.cpp +++ b/src/mame/drivers/opwolf.cpp @@ -272,16 +272,19 @@ register. So what is controlling priority. ***************************************************************************/ #include "emu.h" + +#include "audio/taitosnd.h" +#include "includes/taitoipt.h" +#include "machine/taitocchip.h" +#include "video/pc080sn.h" +#include "video/pc090oj.h" + #include "cpu/m68000/m68000.h" #include "cpu/z80/z80.h" #include "machine/timer.h" -#include "machine/taitocchip.h" #include "sound/msm5205.h" #include "sound/ymopm.h" -#include "includes/taitoipt.h" -#include "video/pc080sn.h" -#include "video/pc090oj.h" -#include "audio/taitosnd.h" + #include "emupal.h" #include "screen.h" #include "speaker.h" @@ -312,7 +315,9 @@ public: m_pc090oj(*this, "pc090oj"), m_msm(*this, "msm%u", 0), m_lspeaker(*this, "lspeaker"), - m_rspeaker(*this, "rspeaker") + m_rspeaker(*this, "rspeaker"), + m_z80bank(*this, "z80bank"), + m_recoil(*this, "Player%u_Recoil_Piston", 1U) { } void opwolf(machine_config &config); @@ -336,7 +341,6 @@ private: void opwolf_adpcm_d_w(uint8_t data); void opwolf_adpcm_e_w(uint8_t data); void opwolf_spritectrl_w(offs_t offset, uint16_t data); - void sound_bankswitch_w(uint8_t data); void opwolf_adpcm_b_w(offs_t offset, uint8_t data); void opwolf_adpcm_c_w(offs_t offset, uint8_t data); void counters_w(uint8_t data); @@ -382,6 +386,8 @@ private: required_device_array m_msm; required_device m_lspeaker; required_device m_rspeaker; + required_memory_bank m_z80bank; + output_finder<1> m_recoil; }; @@ -461,7 +467,7 @@ void opwolf_state::opwolfp_map(address_map &map) void opwolf_state::opwolf_sound_z80_map(address_map &map) { map(0x0000, 0x3fff).rom(); - map(0x4000, 0x7fff).bankr("z80bank"); + map(0x4000, 0x7fff).bankr(m_z80bank); map(0x8000, 0x8fff).ram(); map(0x9000, 0x9001).rw("ymsnd", FUNC(ym2151_device::read), FUNC(ym2151_device::write)); map(0x9002, 0x9100).nopr(); @@ -644,31 +650,24 @@ void opwolf_state::opwolf_spritectrl_w(offs_t offset, uint16_t data) // popmessage("opwolf_spritectrl_w ctrl = %4x", data); if (offset == 0) { - /* bit 0 -> MOTOR1 transistor */ - /* bit 1 -> MOTOR2 transistor */ - /* bit 2 -> Reset c-chip and coin custom PC050CM (active low) */ - /* bit 3 -> Not connected */ - /* bit 4 -> LATCH - used to signal light gun position can be latched to inputs on v-blank */ - /* bits 5-7 are the sprite palette bank */ + // bit 0 -> MOTOR1 transistor + // bit 1 -> MOTOR2 transistor + // bit 2 -> Reset c-chip and coin custom PC050CM (active low) + // bit 3 -> Not connected + // bit 4 -> LATCH - used to signal light gun position can be latched to inputs on v-blank + // bits 5-7 are the sprite palette bank m_pc090oj->sprite_ctrl_w(data); - /* If data & 3, the Piston Motor is activated via M-1/M-2 connector */ - if (data & 3) - { - output().set_value("Player1_Recoil_Piston", 1); - } - else - { - output().set_value("Player1_Recoil_Piston", 0); - } + // If data & 3, the Piston Motor is activated via M-1/M-2 connector + m_recoil[0] = (data & 3) ? 1 : 0; } } void opwolf_state::opwolf_colpri_cb(u32 &sprite_colbank, u32 &pri_mask, u16 sprite_ctrl) { sprite_colbank = (sprite_ctrl & 0xe0) >> 1; - pri_mask = 0xfc; /* sprites under top bg layer */ + pri_mask = 0xfc; // sprites under top bg layer } uint32_t opwolf_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) @@ -709,11 +708,6 @@ GFXDECODE_END // SOUND //************************************************************************** -void opwolf_state::sound_bankswitch_w(uint8_t data) -{ - membank("z80bank")->set_entry(data & 0x03); -} - //0 - start ROM offset LSB //1 - start ROM offset MSB //2 - end ROM offset LSB @@ -817,8 +811,6 @@ void opwolf_state::init_opwolf() // World & US version have different gun offsets, presumably slightly different gun hardware m_opwolf_gun_xoffs = 0xec - (rom[0x03ffb0 / 2] & 0xff); m_opwolf_gun_yoffs = 0x1c - (rom[0x03ffae / 2] & 0xff); - - membank("z80bank")->configure_entries(0, 4, memregion("audiocpu")->base(), 0x4000); } void opwolf_state::init_opwolfb() @@ -826,20 +818,20 @@ void opwolf_state::init_opwolfb() /* bootleg needs different range of raw gun coords */ m_opwolf_gun_xoffs = -2; m_opwolf_gun_yoffs = 17; - - membank("z80bank")->configure_entries(0, 4, memregion("audiocpu")->base(), 0x4000); } void opwolf_state::init_opwolfp() { m_opwolf_gun_xoffs = 5; m_opwolf_gun_yoffs = 30; - - membank("z80bank")->configure_entries(0, 4, memregion("audiocpu")->base(), 0x4000); } void opwolf_state::machine_start() { + m_recoil.resolve(); + + m_z80bank->configure_entries(0, 4, memregion("audiocpu")->base(), 0x4000); + save_item(NAME(m_sprite_ctrl)); save_item(NAME(m_sprites_flipscreen)); @@ -938,7 +930,7 @@ void opwolf_state::opwolf(machine_config &config) ym2151_device &ymsnd(YM2151(config, "ymsnd", SOUND_CPU_CLOCK)); /* 4 MHz */ ymsnd.irq_handler().set_inputline(m_audiocpu, 0); - ymsnd.port_write_handler().set(FUNC(opwolf_state::sound_bankswitch_w)); + ymsnd.port_write_handler().set_membank(m_z80bank).mask(0x03); ymsnd.add_route(0, "lspeaker", 1.0); ymsnd.add_route(1, "rspeaker", 1.0); @@ -1012,7 +1004,7 @@ void opwolf_state::opwolfb(machine_config &config) /* OSC clocks unknown for the ym2151_device &ymsnd(YM2151(config, "ymsnd", SOUND_CPU_CLOCK)); ymsnd.irq_handler().set_inputline(m_audiocpu, 0); - ymsnd.port_write_handler().set(FUNC(opwolf_state::sound_bankswitch_w)); + ymsnd.port_write_handler().set_membank(m_z80bank).mask(0x03); ymsnd.add_route(0, "lspeaker", 1.0); ymsnd.add_route(1, "rspeaker", 1.0); diff --git a/src/mame/drivers/videopkr.cpp b/src/mame/drivers/videopkr.cpp index bc170d3e473..be93ff73db5 100644 --- a/src/mame/drivers/videopkr.cpp +++ b/src/mame/drivers/videopkr.cpp @@ -315,7 +315,6 @@ public: , m_maincpu(*this, "maincpu") , m_soundcpu(*this, "soundcpu") , m_gfxdecode(*this, "gfxdecode") - , m_aysnd(*this, "aysnd") , m_digits(*this, "digit%u", 0U) , m_lamps(*this, "lamp%u", 0U) { } @@ -323,15 +322,13 @@ public: void videopkr(machine_config &config); void blckjack(machine_config &config); void videodad(machine_config &config); - void babypkr(machine_config &config); void fortune1(machine_config &config); - void bpoker(machine_config &config); protected: virtual void machine_start() override; virtual void video_start() override; -private: +//private: uint8_t videopkr_io_r(offs_t offset); void videopkr_io_w(offs_t offset, uint8_t data); uint8_t videopkr_p1_data_r(); @@ -344,14 +341,9 @@ private: void sound_io_w(uint8_t data); uint8_t sound_p2_r(); void sound_p2_w(uint8_t data); - uint8_t baby_sound_p0_r(); - void baby_sound_p0_w(uint8_t data); - uint8_t baby_sound_p1_r(); - void baby_sound_p3_w(uint8_t data); TILE_GET_INFO_MEMBER(get_bg_tile_info); void videopkr_palette(palette_device &palette) const; DECLARE_VIDEO_START(vidadcba); - void babypkr_palette(palette_device &palette) const; void fortune1_palette(palette_device &palette) const; uint32_t screen_update_videopkr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); TIMER_DEVICE_CALLBACK_MEMBER(sound_t1_callback); @@ -361,10 +353,6 @@ private: void i8039_map(address_map &map); void i8039_sound_mem(address_map &map); void i8039_sound_port(address_map &map); - void i8051_sound_mem(address_map &map); - void i8051_sound_port(address_map &map); - void i8751_io_port(address_map &map); - void i8751_map(address_map &map); memory_share_creator m_data_ram; memory_share_creator m_video_ram; @@ -395,17 +383,50 @@ private: unsigned long m_count2; unsigned long m_count3; unsigned long m_count4; - uint8_t m_sbp0; tilemap_t *m_bg_tilemap; required_device m_maincpu; required_device m_soundcpu; required_device m_gfxdecode; - optional_device m_aysnd; output_finder<28> m_digits; output_finder<14> m_lamps; }; +class babypkr_state : public videopkr_state +{ +public: + babypkr_state(const machine_config &mconfig, device_type type, const char *tag) + : videopkr_state(mconfig, type, tag) + , m_aysnd(*this, "aysnd") + , m_top_lamps(*this, "TOP_%u", 1U) + { + } + + void babypkr(machine_config &config); + void bpoker(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + uint8_t baby_sound_p0_r(); + void baby_sound_p0_w(uint8_t data); + uint8_t baby_sound_p1_r(); + void baby_sound_p3_w(uint8_t data); + void babypkr_palette(palette_device &palette) const; + + void i8751_map(address_map &map); + void i8751_io_port(address_map &map); + void i8051_sound_mem(address_map &map); + void i8051_sound_port(address_map &map); + + required_device m_aysnd; + output_finder<3> m_top_lamps; + + uint8_t m_sbp0; +}; + + #define DATA_NVRAM_SIZE 0x100 /************************* @@ -468,7 +489,7 @@ void videopkr_state::videopkr_palette(palette_device &palette) const } } -void videopkr_state::babypkr_palette(palette_device &palette) const +void babypkr_state::babypkr_palette(palette_device &palette) const { uint8_t const *const color_prom = memregion("proms")->base(); for (int j = 0; j < palette.entries(); j++) @@ -875,17 +896,17 @@ void videopkr_state::sound_p2_w(uint8_t data) /* Baby Sound Handlers */ -uint8_t videopkr_state::baby_sound_p0_r() +uint8_t babypkr_state::baby_sound_p0_r() { return m_sbp0; } -void videopkr_state::baby_sound_p0_w(uint8_t data) +void babypkr_state::baby_sound_p0_w(uint8_t data) { m_sbp0 = data; } -uint8_t videopkr_state::baby_sound_p1_r() +uint8_t babypkr_state::baby_sound_p1_r() { m_c_io = (m_p1 >> 5) & 1; m_hp_1 = (~m_p24_data >> 6) & 1; @@ -895,14 +916,11 @@ uint8_t videopkr_state::baby_sound_p1_r() return m_c_io | (m_hp_1 << 1) | (m_hp_2 << 2) | (m_bell << 3) | (m_aux3 << 4) | 0xe0; } -void videopkr_state::baby_sound_p3_w(uint8_t data) +void babypkr_state::baby_sound_p3_w(uint8_t data) { - uint8_t lmp_ports, ay_intf; - lmp_ports = data >> 1 & 0x07; - - output().set_value("TOP_1", (lmp_ports >> 0) & 1); - output().set_value("TOP_2", (lmp_ports >> 1) & 1); - output().set_value("TOP_3", (lmp_ports >> 2) & 1); + m_top_lamps[0] = BIT(data, 1); + m_top_lamps[1] = BIT(data, 2); + m_top_lamps[2] = BIT(data, 3); if (!(data & 0x10)) { @@ -910,8 +928,7 @@ void videopkr_state::baby_sound_p3_w(uint8_t data) logerror("AY3-8910: Reset\n"); } - ay_intf = (data >> 5) & 0x07; - + uint8_t ay_intf = (data >> 5) & 0x07; switch (ay_intf) { case 0x00: break; @@ -953,12 +970,12 @@ void videopkr_state::i8039_io_port(address_map &map) map(0x00, 0xff).rw(FUNC(videopkr_state::videopkr_io_r), FUNC(videopkr_state::videopkr_io_w)); } -void videopkr_state::i8751_map(address_map &map) +void babypkr_state::i8751_map(address_map &map) { map(0x0000, 0x7fff).rom(); } -void videopkr_state::i8751_io_port(address_map &map) +void babypkr_state::i8751_io_port(address_map &map) { map(0x0000, 0x0fff).ram(); // NVRAM? map(0x8000, 0x8000).noprw(); // ??? @@ -979,12 +996,12 @@ void videopkr_state::i8039_sound_port(address_map &map) } -void videopkr_state::i8051_sound_mem(address_map &map) +void babypkr_state::i8051_sound_mem(address_map &map) { map(0x0000, 0x0fff).rom(); } -void videopkr_state::i8051_sound_port(address_map &map) +void babypkr_state::i8051_sound_port(address_map &map) { map(0x0000, 0x1ff).ram(); } @@ -1212,6 +1229,7 @@ void videopkr_state::machine_start() { m_digits.resolve(); m_lamps.resolve(); + m_vp_sound_p2 = 0xff; /* default P2 latch value */ m_sound_latch = 0xff; /* default sound data latch value */ m_p24_data = 0xff; @@ -1227,6 +1245,13 @@ void videopkr_state::machine_start() subdevice("nvram")->set_base(m_data_ram, sizeof(m_data_ram)); } +void babypkr_state::machine_start() +{ + videopkr_state::machine_start(); + + m_top_lamps.resolve(); +} + /************************ * Machine Drivers * ************************/ @@ -1303,8 +1328,19 @@ void videopkr_state::videodad(machine_config &config) MCFG_VIDEO_START_OVERRIDE(videopkr_state,vidadcba) } +void videopkr_state::fortune1(machine_config &config) +{ + videopkr(config); + + /* basic machine hardware */ + m_maincpu->set_clock(CPU_CLOCK_ALT); + + /* video hardware */ + subdevice("palette")->set_init(FUNC(videopkr_state::fortune1_palette)); +} + -void videopkr_state::babypkr(machine_config &config) +void babypkr_state::babypkr(machine_config &config) { videopkr(config); @@ -1313,43 +1349,34 @@ void videopkr_state::babypkr(machine_config &config) /* most likely romless or eprom */ i8031_device &soundcpu(I8031(config.replace(), m_soundcpu, CPU_CLOCK)); - soundcpu.set_addrmap(AS_PROGRAM, &videopkr_state::i8051_sound_mem); - soundcpu.set_addrmap(AS_IO, &videopkr_state::i8051_sound_port); - soundcpu.port_in_cb<0>().set(FUNC(videopkr_state::baby_sound_p0_r)); - soundcpu.port_out_cb<0>().set(FUNC(videopkr_state::baby_sound_p0_w)); - soundcpu.port_in_cb<1>().set(FUNC(videopkr_state::baby_sound_p1_r)); + soundcpu.set_addrmap(AS_PROGRAM, &babypkr_state::i8051_sound_mem); + soundcpu.set_addrmap(AS_IO, &babypkr_state::i8051_sound_port); + soundcpu.port_in_cb<0>().set(FUNC(babypkr_state::baby_sound_p0_r)); + soundcpu.port_out_cb<0>().set(FUNC(babypkr_state::baby_sound_p0_w)); + soundcpu.port_in_cb<1>().set(FUNC(babypkr_state::baby_sound_p1_r)); soundcpu.port_out_cb<2>().set("dac", FUNC(dac_byte_interface::data_w)); - soundcpu.port_out_cb<3>().set(FUNC(videopkr_state::baby_sound_p3_w)); + soundcpu.port_out_cb<3>().set(FUNC(babypkr_state::baby_sound_p3_w)); /* video hardware */ screen_device &screen(*subdevice("screen")); screen.set_size(32*16, 32*8); screen.set_visarea(5*16, 31*16-1, 3*8, 29*8-1); - subdevice("palette")->set_init(FUNC(videopkr_state::babypkr_palette)); + subdevice("palette")->set_init(FUNC(babypkr_state::babypkr_palette)); m_gfxdecode->set_info(gfx_videodad); - MCFG_VIDEO_START_OVERRIDE(videopkr_state,vidadcba) - - AY8910(config, m_aysnd, CPU_CLOCK / 6).add_route(ALL_OUTPUTS, "speaker", 0.3); /* no ports used */ -} - -void videopkr_state::fortune1(machine_config &config) -{ - videopkr(config); + MCFG_VIDEO_START_OVERRIDE(babypkr_state,vidadcba) - /* basic machine hardware */ - m_maincpu->set_clock(CPU_CLOCK_ALT); - - subdevice("palette")->set_init(FUNC(videopkr_state::fortune1_palette)); + AY8910(config, m_aysnd, CPU_CLOCK / 6); // no ports used + m_aysnd->add_route(ALL_OUTPUTS, "speaker", 0.3); } -void videopkr_state::bpoker(machine_config &config) +void babypkr_state::bpoker(machine_config &config) { babypkr(config); i8751_device &maincpu(I8751(config.replace(), m_maincpu, XTAL(6'000'000))); - maincpu.set_addrmap(AS_PROGRAM, &videopkr_state::i8751_map); - maincpu.set_addrmap(AS_IO, &videopkr_state::i8751_io_port); + maincpu.set_addrmap(AS_PROGRAM, &babypkr_state::i8751_map); + maincpu.set_addrmap(AS_IO, &babypkr_state::i8751_io_port); maincpu.port_in_cb<0>().set_constant(0); // ??? maincpu.port_in_cb<1>().set_constant(0); // ??? maincpu.port_out_cb<1>().set_nop(); // ??? @@ -1590,6 +1617,6 @@ GAMEL( 1984, fortune1, videopkr, fortune1, videopkr, videopkr_state, empty_init, GAMEL( 1984, blckjack, videopkr, blckjack, blckjack, videopkr_state, empty_init, ROT0, "InterFlip", "Black Jack", 0, layout_blckjack ) GAMEL( 1987, videodad, videopkr, videodad, videodad, videopkr_state, empty_init, ROT0, "InterFlip", "Video Dado", 0, layout_videodad ) GAMEL( 1987, videocba, videopkr, videodad, videocba, videopkr_state, empty_init, ROT0, "InterFlip", "Video Cordoba", 0, layout_videocba ) -GAMEL( 1987, babypkr, videopkr, babypkr, babypkr, videopkr_state, empty_init, ROT0, "Recreativos Franco", "Baby Poker", 0, layout_babypkr ) -GAMEL( 1987, babydad, videopkr, babypkr, babydad, videopkr_state, empty_init, ROT0, "Recreativos Franco", "Baby Dado", 0, layout_babydad ) -GAMEL( 198?, bpoker, videopkr, bpoker, babypkr, videopkr_state, empty_init, ROT0, "Recreativos Franco", "Video Poker (v1403)", MACHINE_NOT_WORKING, layout_babypkr ) +GAMEL( 1987, babypkr, videopkr, babypkr, babypkr, babypkr_state, empty_init, ROT0, "Recreativos Franco", "Baby Poker", 0, layout_babypkr ) +GAMEL( 1987, babydad, videopkr, babypkr, babydad, babypkr_state, empty_init, ROT0, "Recreativos Franco", "Baby Dado", 0, layout_babydad ) +GAMEL( 198?, bpoker, videopkr, bpoker, babypkr, babypkr_state, empty_init, ROT0, "Recreativos Franco", "Video Poker (v1403)", MACHINE_NOT_WORKING, layout_babypkr ) diff --git a/src/mame/includes/exidy.h b/src/mame/includes/exidy.h deleted file mode 100644 index 227d51a635a..00000000000 --- a/src/mame/includes/exidy.h +++ /dev/null @@ -1,156 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/************************************************************************* - - Exidy 6502 hardware - -*************************************************************************/ - -#include "sound/dac.h" -#include "sound/samples.h" -#include "emupal.h" -#include "screen.h" - -#define EXIDY_MASTER_CLOCK (XTAL(11'289'000)) -#define EXIDY_CPU_CLOCK (EXIDY_MASTER_CLOCK / 16) -#define EXIDY_PIXEL_CLOCK (EXIDY_MASTER_CLOCK / 2) -#define EXIDY_HTOTAL (0x150) -#define EXIDY_HBEND (0x000) -#define EXIDY_HBSTART (0x100) -#define EXIDY_HSEND (0x140) -#define EXIDY_HSSTART (0x120) -#define EXIDY_VTOTAL (0x118) -#define EXIDY_VBEND (0x000) -#define EXIDY_VBSTART (0x100) -#define EXIDY_VSEND (0x108) -#define EXIDY_VSSTART (0x100) - - -class exidy_state : public driver_device -{ -public: - enum - { - TIMER_COLLISION_IRQ - }; - - exidy_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_dac(*this, "dac"), - m_samples(*this, "samples"), - m_gfxdecode(*this, "gfxdecode"), - m_screen(*this, "screen"), - m_palette(*this, "palette"), - m_videoram(*this, "videoram"), - m_sprite1_xpos(*this, "sprite1_xpos"), - m_sprite1_ypos(*this, "sprite1_ypos"), - m_sprite2_xpos(*this, "sprite2_xpos"), - m_sprite2_ypos(*this, "sprite2_ypos"), - m_spriteno(*this, "spriteno"), - m_sprite_enable(*this, "sprite_enable"), - m_color_latch(*this, "color_latch"), - m_characterram(*this, "characterram") { } - - void base(machine_config &config); - void mtrap(machine_config &config); - void venture(machine_config &config); - void fax(machine_config &config); - void teetert(machine_config &config); - void sidetrac(machine_config &config); - void spectar(machine_config &config); - void spectar_audio(machine_config &config); - void rallys(machine_config &config); - void pepper2(machine_config &config); - void targ(machine_config &config); - void targ_audio(machine_config &config); - - void init_fax(); - void init_sidetrac(); - void init_pepper2(); - void init_targ(); - void init_rallys(); - void init_mtrap(); - void init_teetert(); - void init_venture(); - void init_spectar(); - void init_phantoma(); - - DECLARE_CUSTOM_INPUT_MEMBER(teetert_input_r); - -private: - required_device m_maincpu; - optional_device m_dac; - optional_device m_samples; - required_device m_gfxdecode; - required_device m_screen; - required_device m_palette; - - required_shared_ptr m_videoram; - required_shared_ptr m_sprite1_xpos; - required_shared_ptr m_sprite1_ypos; - required_shared_ptr m_sprite2_xpos; - required_shared_ptr m_sprite2_ypos; - required_shared_ptr m_spriteno; - required_shared_ptr m_sprite_enable; - required_shared_ptr m_color_latch; - optional_shared_ptr m_characterram; - - uint8_t m_last_dial; - uint8_t m_collision_mask; - uint8_t m_collision_invert; - int m_is_2bpp; - uint8_t m_int_condition; - bitmap_ind16 m_background_bitmap; - bitmap_ind16 m_motion_object_1_vid; - bitmap_ind16 m_motion_object_2_vid; - bitmap_ind16 m_motion_object_2_clip; - - void fax_bank_select_w(uint8_t data); - uint8_t exidy_interrupt_r(); - void mtrap_ocl_w(uint8_t data); - - virtual void video_start() override; - DECLARE_MACHINE_START(teetert); - - uint32_t screen_update_exidy(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - - INTERRUPT_GEN_MEMBER(exidy_vblank_interrupt); - - void exidy_video_config(uint8_t _collision_mask, uint8_t _collision_invert, int _is_2bpp); - inline void latch_condition(int collision); - inline void set_1_color(int index, int which); - void set_colors(); - void draw_background(); - inline int sprite_1_enabled(); - void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect); - void check_collision(); - - /* Targ and Spectar samples */ - int m_max_freq; - uint8_t m_port_1_last; - uint8_t m_port_2_last; - uint8_t m_tone_freq; - uint8_t m_tone_active; - uint8_t m_tone_pointer; - void targ_audio_1_w(uint8_t data); - void targ_audio_2_w(uint8_t data); - void spectar_audio_2_w(uint8_t data); - void adjust_sample(uint8_t freq); - void common_audio_start(int freq); - SAMPLES_START_CB_MEMBER(spectar_audio_start); - SAMPLES_START_CB_MEMBER(targ_audio_start); - - void exidy_map(address_map &map); - void fax_map(address_map &map); - void mtrap_map(address_map &map); - void pepper2_map(address_map &map); - void rallys_map(address_map &map); - void sidetrac_map(address_map &map); - void spectar_map(address_map &map); - void targ_map(address_map &map); - void venture_map(address_map &map); - -protected: - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; -}; diff --git a/src/mame/video/exidy.cpp b/src/mame/video/exidy.cpp deleted file mode 100644 index e5cc24134e7..00000000000 --- a/src/mame/video/exidy.cpp +++ /dev/null @@ -1,374 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/************************************************************************* - - Exidy 6502 hardware - -*************************************************************************/ - -#include "emu.h" -#include "includes/exidy.h" - - - -/************************************* - * - * Video configuration - * - *************************************/ - -void exidy_state::exidy_video_config(uint8_t _collision_mask, uint8_t _collision_invert, int _is_2bpp) -{ - m_collision_mask = _collision_mask; - m_collision_invert = _collision_invert; - m_is_2bpp = _is_2bpp; -} - - - -/************************************* - * - * Video startup - * - *************************************/ - -void exidy_state::video_start() -{ - m_screen->register_screen_bitmap(m_background_bitmap); - m_motion_object_1_vid.allocate(16, 16); - m_motion_object_2_vid.allocate(16, 16); - m_motion_object_2_clip.allocate(16, 16); - - save_item(NAME(m_collision_mask)); - save_item(NAME(m_collision_invert)); - save_item(NAME(m_is_2bpp)); - save_item(NAME(m_int_condition)); - save_item(NAME(m_background_bitmap)); - save_item(NAME(m_motion_object_1_vid)); - save_item(NAME(m_motion_object_2_vid)); - save_item(NAME(m_motion_object_2_clip)); -} - - - -/************************************* - * - * Interrupt generation - * - *************************************/ - -inline void exidy_state::latch_condition(int collision) -{ - collision ^= m_collision_invert; - m_int_condition = (ioport("INTSOURCE")->read() & ~0x1c) | (collision & m_collision_mask); -} - - -INTERRUPT_GEN_MEMBER(exidy_state::exidy_vblank_interrupt) -{ - /* latch the current condition */ - latch_condition(0); - m_int_condition &= ~0x80; - - /* set the IRQ line */ - device.execute().set_input_line(0, ASSERT_LINE); -} - - - -uint8_t exidy_state::exidy_interrupt_r() -{ - /* clear any interrupts */ - m_maincpu->set_input_line(0, CLEAR_LINE); - - /* return the latched condition */ - return m_int_condition; -} - - - -/************************************* - * - * Palette handling - * - *************************************/ - -inline void exidy_state::set_1_color(int index, int which) -{ - m_palette->set_pen_color(index, - pal1bit(m_color_latch[2] >> which), - pal1bit(m_color_latch[1] >> which), - pal1bit(m_color_latch[0] >> which)); -} - -void exidy_state::set_colors() -{ - /* motion object 1 */ - set_1_color(0, 0); - set_1_color(1, 7); - - /* motion object 2 */ - set_1_color(2, 0); - set_1_color(3, 6); - - /* characters */ - set_1_color(4, 4); - set_1_color(5, 3); - set_1_color(6, 2); - set_1_color(7, 1); -} - - - -/************************************* - * - * Background update - * - *************************************/ - -void exidy_state::draw_background() -{ - const u8 *cram = m_characterram ? (u8 *)m_characterram : memregion("maincpu")->base() + 0x4800; - offs_t offs; - - pen_t off_pen = 0; - - for (offs = 0; offs < 0x400; offs++) - { - uint8_t y = offs >> 5 << 3; - uint8_t const code = m_videoram[offs]; - - pen_t on_pen_1, on_pen_2; - if (m_is_2bpp) - { - on_pen_1 = 4 + ((code >> 6) & 0x02); - on_pen_2 = 5 + ((code >> 6) & 0x02); - } - else - { - on_pen_1 = 4 + ((code >> 6) & 0x03); - on_pen_2 = off_pen; /* unused */ - } - - for (uint8_t cy = 0; cy < 8; cy++) - { - uint8_t x = offs << 3; - - if (m_is_2bpp) - { - uint8_t data1 = cram[0x000 | (code << 3) | cy]; - uint8_t data2 = cram[0x800 | (code << 3) | cy]; - - for (int i = 0; i < 8; i++) - { - if (data1 & 0x80) - m_background_bitmap.pix(y, x) = (data2 & 0x80) ? on_pen_2 : on_pen_1; - else - m_background_bitmap.pix(y, x) = off_pen; - - x++; - data1 <<= 1; - data2 <<= 1; - } - } - /* 1bpp */ - else - { - uint8_t data = cram[(code << 3) | cy]; - - for (int i = 0; i < 8; i++) - { - m_background_bitmap.pix(y, x) = (data & 0x80) ? on_pen_1 : off_pen; - - x++; - data <<= 1; - } - } - - y++; - } - } -} - - - -/************************************* - * - * Sprite hardware - * - *************************************/ - -inline int exidy_state::sprite_1_enabled() -{ - /* if the collision_mask is 0x00, then we are on old hardware that always has */ - /* sprite 1 enabled regardless */ - return (!(*m_sprite_enable & 0x80) || (*m_sprite_enable & 0x10) || (m_collision_mask == 0x00)); -} - - -void exidy_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - /* draw sprite 2 first */ - int sprite_set_2 = ((*m_sprite_enable & 0x40) != 0); - - int sx = 236 - *m_sprite2_xpos - 4; - int sy = 244 - *m_sprite2_ypos - 4; - - m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, - ((*m_spriteno >> 4) & 0x0f) + 32 + 16 * sprite_set_2, 1, - 0, 0, sx, sy, 0); - - /* draw sprite 1 next */ - if (sprite_1_enabled()) - { - int sprite_set_1 = ((*m_sprite_enable & 0x20) != 0); - - sx = 236 - *m_sprite1_xpos - 4; - sy = 244 - *m_sprite1_ypos - 4; - - if (sy < 0) sy = 0; - - m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, - (*m_spriteno & 0x0f) + 16 * sprite_set_1, 0, - 0, 0, sx, sy, 0); - } - -} - - - -/************************************* - * - * Collision detection - * - *************************************/ - -/*************************************************************************** - - Exidy hardware checks for two types of collisions based on the video - signals. If the Motion Object 1 and Motion Object 2 signals are on at - the same time, an M1M2 collision bit gets set. If the Motion Object 1 - and Background Character signals are on at the same time, an M1CHAR - collision bit gets set. So effectively, there's a pixel-by-pixel - collision check comparing Motion Object 1 (the player) to the - background and to the other Motion Object (typically a bad guy). - -***************************************************************************/ - -void exidy_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch (id) - { - case TIMER_COLLISION_IRQ: - /* latch the collision bits */ - latch_condition(param); - - /* set the IRQ line */ - m_maincpu->set_input_line(0, ASSERT_LINE); - - break; - default: - throw emu_fatalerror("Unknown id in exidy_state::device_timer"); - } -} - - -void exidy_state::check_collision() -{ - uint8_t sprite_set_1 = ((*m_sprite_enable & 0x20) != 0); - uint8_t sprite_set_2 = ((*m_sprite_enable & 0x40) != 0); - const rectangle clip(0, 15, 0, 15); - int org_1_x = 0, org_1_y = 0; - int org_2_x = 0, org_2_y = 0; - int count = 0; - - /* if there is nothing to detect, bail */ - if (m_collision_mask == 0) - return; - - /* draw sprite 1 */ - m_motion_object_1_vid.fill(0xff, clip); - if (sprite_1_enabled()) - { - org_1_x = 236 - *m_sprite1_xpos - 4; - org_1_y = 244 - *m_sprite1_ypos - 4; - m_gfxdecode->gfx(0)->transpen(m_motion_object_1_vid,clip, - (*m_spriteno & 0x0f) + 16 * sprite_set_1, 0, - 0, 0, 0, 0, 0); - } - - /* draw sprite 2 */ - m_motion_object_2_vid.fill(0xff, clip); - org_2_x = 236 - *m_sprite2_xpos - 4; - org_2_y = 244 - *m_sprite2_ypos - 4; - m_gfxdecode->gfx(0)->transpen(m_motion_object_2_vid,clip, - ((*m_spriteno >> 4) & 0x0f) + 32 + 16 * sprite_set_2, 0, - 0, 0, 0, 0, 0); - - /* draw sprite 2 clipped to sprite 1's location */ - m_motion_object_2_clip.fill(0xff, clip); - if (sprite_1_enabled()) - { - int sx = org_2_x - org_1_x; - int sy = org_2_y - org_1_y; - m_gfxdecode->gfx(0)->transpen(m_motion_object_2_clip,clip, - ((*m_spriteno >> 4) & 0x0f) + 32 + 16 * sprite_set_2, 0, - 0, 0, sx, sy, 0); - } - - /* scan for collisions */ - for (int sy = 0; sy < 16; sy++) - for (int sx = 0; sx < 16; sx++) - { - if (m_motion_object_1_vid.pix(sy, sx) != 0xff) - { - uint8_t current_collision_mask = 0; - - /* check for background collision (M1CHAR) */ - if (m_background_bitmap.pix(org_1_y + sy, org_1_x + sx) != 0) - current_collision_mask |= 0x04; - - /* check for motion object collision (M1M2) */ - if (m_motion_object_2_clip.pix(sy, sx) != 0xff) - current_collision_mask |= 0x10; - - /* if we got one, trigger an interrupt */ - if ((current_collision_mask & m_collision_mask) && (count++ < 128)) - timer_set(m_screen->time_until_pos(org_1_x + sx, org_1_y + sy), TIMER_COLLISION_IRQ, current_collision_mask); - } - - if (m_motion_object_2_vid.pix(sy, sx) != 0xff) - { - /* check for background collision (M2CHAR) */ - if (m_background_bitmap.pix(org_2_y + sy, org_2_x + sx) != 0) - if ((m_collision_mask & 0x08) && (count++ < 128)) - timer_set(m_screen->time_until_pos(org_2_x + sx, org_2_y + sy), TIMER_COLLISION_IRQ, 0x08); - } - } -} - - - -/************************************* - * - * Standard screen refresh callback - * - *************************************/ - -uint32_t exidy_state::screen_update_exidy(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - /* refresh the colors from the palette (static or dynamic) */ - set_colors(); - - /* update the background and draw it */ - draw_background(); - copybitmap(bitmap, m_background_bitmap, 0, 0, 0, 0, cliprect); - - /* draw the sprites */ - draw_sprites(bitmap, cliprect); - - /* check for collision, this will set the appropriate bits in collision_mask */ - check_collision(); - - return 0; -} -- cgit v1.2.3