diff options
author | 2019-12-16 00:09:21 +0100 | |
---|---|---|
committer | 2019-12-16 00:09:48 +0100 | |
commit | 9c03fc73456877aa21ec8aaffe62f415ef6364bf (patch) | |
tree | 0d4a20389070d8242cb93d6cb99f2da3d4a8bd78 | |
parent | ea878703face05e13a9c3c0cc967008fb77b367f (diff) |
cgang: added stepper motors (nw)
-rw-r--r-- | src/devices/machine/ticket.cpp | 2 | ||||
-rw-r--r-- | src/mame/drivers/cgang.cpp | 332 |
2 files changed, 248 insertions, 86 deletions
diff --git a/src/devices/machine/ticket.cpp b/src/devices/machine/ticket.cpp index f18faa45aab..8063d4c41e5 100644 --- a/src/devices/machine/ticket.cpp +++ b/src/devices/machine/ticket.cpp @@ -51,7 +51,7 @@ ticket_dispenser_device::ticket_dispenser_device(const machine_config &mconfig, , m_status(0) , m_power(0) , m_timer(nullptr) - , m_output(*this, "led2") // TODO: probably shouldn't be hardcoded + , m_output(*this, "led2") // TODO: shouldn't be hardcoded { } diff --git a/src/mame/drivers/cgang.cpp b/src/mame/drivers/cgang.cpp index 1616795782d..8740040135e 100644 --- a/src/mame/drivers/cgang.cpp +++ b/src/mame/drivers/cgang.cpp @@ -5,14 +5,16 @@ 『コズモギャングス』 (COSMOGANGS) by Namco, 1990. USA distribution was handled by Data East, they titled it "Cosmo Gang". -It is an electromechanical arcade lightgun game with ticket redemption. -There is no screen, feedback is with motorized elements, lamps and 7segs, -and of course sounds and music. - -The hardware has similarities with Gator Panic/Wacky Gator. +It is an electromechanical arcade lightgun game. There is no screen, feedback +is with motorized elements, lamps and 7segs, and of course sounds and music. TODO: -- almost everything +- internal artwork +- game can't really be played within MAME's constraints (mechanical stuff, + and the lightguns linked to it) +- ppi2_b_r cabinet center sensors, doesn't seem to affect the game at all + +------------------------------------------------------------------------------- Hardware notes: @@ -33,12 +35,15 @@ Audio CPU side: Cabinet: - 5 lanes with movable aliens, lightsensor under mouth -- 5 'energy containers', aliens will try to steal them +- 5 'energy crates', aliens will try to steal them - 2 lightguns - UFO with leds above cabinet +- sliding door (only for Japan version?) - 7segs for scorekeeping - 2 speakers (but final mix is mono!) -- ticket dispenser +- optional ticket/prize dispenser + +Overall, the hardware has similarities with Wacky Gator, see wacky_gator.cpp. ******************************************************************************/ @@ -49,6 +54,7 @@ Cabinet: #include "machine/i8255.h" #include "machine/pit8253.h" #include "machine/ripple_counter.h" +#include "machine/ticket.h" #include "machine/timer.h" #include "machine/watchdog.h" #include "sound/upd7759.h" @@ -60,8 +66,12 @@ Cabinet: namespace { -// length of the gate/door in msec (time it takes to open or close) -static constexpr int GATE_MOTOR_LIMIT = 2500; +// length of the sliding door in msec (time it takes to open or close) +static constexpr int DOOR_MOTOR_LIMIT = 2000; + +// length of each cosmogang lane, in motor steps +// at game start, one cosmo going forward takes around 6-7 seconds (compared to video recording) +static constexpr int CG_MOTOR_LIMIT = 850; class cgang_state : public driver_device @@ -75,10 +85,12 @@ public: m_latch(*this, "latch%u", 0), m_pit(*this, "pit%u", 0), m_ppi(*this, "ppi%u", 0), + m_ticket(*this, "ticket"), m_adpcm(*this, "adpcm%u", 0), m_ymsnd(*this, "ymsnd"), m_digits(*this, "digits"), - m_inputs(*this, "IN%u", 1), + m_fake(*this, "FAKE%u", 1), + m_conf(*this, "CONF1"), m_dipsw(*this, "SW%u", 1), m_gun_lamps(*this, "gun_lamp%u", 0U), m_spot_lamps(*this, "spot_lamp%u", 0U), @@ -86,7 +98,10 @@ public: m_ufo_lamps(*this, "ufo_lamp%u", 0U), m_ufo_sol(*this, "ufo_sol"), m_en_sol(*this, "en_sol%u", 0U), - m_cg_sol(*this, "cg_sol%u", 0U) + m_cg_sol(*this, "cg_sol%u", 0U), + m_door_count(*this, "door_count"), + m_en_count(*this, "en_count%u", 0U), + m_cg_count(*this, "cg_count%u", 0U) { } // machine drivers @@ -94,6 +109,7 @@ public: protected: virtual void machine_start() override; + virtual void machine_reset() override; private: // devices/pointers @@ -103,10 +119,12 @@ private: required_device_array<generic_latch_8_device, 2> m_latch; required_device_array<pit8253_device, 2> m_pit; required_device_array<i8255_device, 5> m_ppi; + required_device<ticket_dispenser_device> m_ticket; required_device_array<upd7759_device, 2> m_adpcm; required_device<ym2151_device> m_ymsnd; required_device<pwm_display_device> m_digits; - required_ioport_array<3> m_inputs; + required_ioport_array<2> m_fake; + required_ioport m_conf; required_ioport_array<4> m_dipsw; output_finder<2> m_gun_lamps; output_finder<8> m_spot_lamps; @@ -115,6 +133,9 @@ private: output_finder<> m_ufo_sol; output_finder<5> m_en_sol; output_finder<5> m_cg_sol; + output_finder<> m_door_count; + output_finder<5> m_en_count; + output_finder<5> m_cg_count; // address maps void main_map(address_map &map); @@ -123,10 +144,12 @@ private: // I/O handlers DECLARE_WRITE_LINE_MEMBER(main_irq_w); DECLARE_WRITE_LINE_MEMBER(main_firq_w); - DECLARE_WRITE8_MEMBER(main_irq_clear_w) { m_maincpu->set_input_line(M6809_IRQ_LINE, CLEAR_LINE); } - DECLARE_WRITE8_MEMBER(main_firq_clear_w) { m_maincpu->set_input_line(M6809_FIRQ_LINE, CLEAR_LINE); } - TIMER_DEVICE_CALLBACK_MEMBER(gate_motor_tick); + DECLARE_WRITE8_MEMBER(main_irq_clear_w); + DECLARE_WRITE8_MEMBER(main_firq_clear_w); template<int N> DECLARE_WRITE_LINE_MEMBER(motor_clock_w); + void cg_motor_tick(int i); + TIMER_DEVICE_CALLBACK_MEMBER(door_motor_tick); + void refresh_motor_output(); DECLARE_READ8_MEMBER(ppi1_b_r); DECLARE_READ8_MEMBER(ppi1_c_r); @@ -136,6 +159,7 @@ private: DECLARE_WRITE8_MEMBER(ppi3_a_w); DECLARE_WRITE8_MEMBER(ppi3_b_w); DECLARE_WRITE8_MEMBER(ppi3_c_w); + void set_en_sol(int i, int state); DECLARE_WRITE8_MEMBER(ppi4_a_w); DECLARE_WRITE8_MEMBER(ppi4_b_w); DECLARE_WRITE8_MEMBER(ppi4_c_w); @@ -150,20 +174,23 @@ private: int m_watchdog_clk = 0; int m_main_irq = 0; int m_main_firq = 0; - u8 m_gate_motor_on = 0; - int m_gate_motor_pos = 0; + u8 m_door_motor_on = 0; + int m_door_motor_pos = 0; u8 m_cg_motor_on = 0; u8 m_cg_motor_dir = 0; int m_cg_motor_clk[5]; + int m_cg_motor_pos[5]; + int m_en_motor_pos[5]; + + emu_timer *m_sol_filter[5]; + TIMER_CALLBACK_MEMBER(output_sol) { m_en_sol[param >> 1] = param & 1; } }; void cgang_state::machine_start() { for (int i = 0; i < 5; i++) - { - m_cg_motor_clk[i] = 0; - } + m_sol_filter[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(cgang_state::output_sol),this)); // resolve outputs m_gun_lamps.resolve(); @@ -173,15 +200,42 @@ void cgang_state::machine_start() m_ufo_sol.resolve(); m_en_sol.resolve(); m_cg_sol.resolve(); + m_door_count.resolve(); + m_en_count.resolve(); + m_cg_count.resolve(); // register for savestates save_item(NAME(m_watchdog_clk)); save_item(NAME(m_main_irq)); save_item(NAME(m_main_firq)); - save_item(NAME(m_gate_motor_on)); - save_item(NAME(m_gate_motor_pos)); + save_item(NAME(m_door_motor_on)); + save_item(NAME(m_door_motor_pos)); save_item(NAME(m_cg_motor_on)); save_item(NAME(m_cg_motor_dir)); + save_item(NAME(m_cg_motor_clk)); + save_item(NAME(m_cg_motor_pos)); + save_item(NAME(m_en_motor_pos)); +} + +void cgang_state::machine_reset() +{ + m_main_irq = 0; + m_main_firq = 0; + + // initial motor positions + for (int i = 0; i < 5; i++) + { + m_cg_motor_clk[i] = 0; + m_cg_motor_pos[i] = 0; + m_en_motor_pos[i] = CG_MOTOR_LIMIT; + m_en_sol[i] = 0; + } + + m_door_motor_pos = 0; + m_door_motor_on = 0; + m_cg_motor_on = 0; + + refresh_motor_output(); } @@ -190,7 +244,7 @@ void cgang_state::machine_start() I/O ******************************************************************************/ -// maincpu +// maincpu (misc) WRITE_LINE_MEMBER(cgang_state::main_irq_w) { @@ -210,76 +264,157 @@ WRITE_LINE_MEMBER(cgang_state::main_firq_w) m_main_firq = state; } -TIMER_DEVICE_CALLBACK_MEMBER(cgang_state::gate_motor_tick) +WRITE8_MEMBER(cgang_state::main_irq_clear_w) { - if (m_gate_motor_on & 2 && m_gate_motor_pos < GATE_MOTOR_LIMIT) - m_gate_motor_pos++; - else if (m_gate_motor_on & 1 && m_gate_motor_pos > 0) - m_gate_motor_pos--; + m_maincpu->set_input_line(M6809_IRQ_LINE, CLEAR_LINE); +} + +WRITE8_MEMBER(cgang_state::main_firq_clear_w) +{ + m_maincpu->set_input_line(M6809_FIRQ_LINE, CLEAR_LINE); } template<int N> WRITE_LINE_MEMBER(cgang_state::motor_clock_w) { - // clock stepper motor - if (state && !m_cg_motor_clk[N]) + // clock stepper motors + if (state && !m_cg_motor_clk[N] && BIT(m_cg_motor_on, N)) + cg_motor_tick(N); + + m_cg_motor_clk[N] = state; +} + +void cgang_state::cg_motor_tick(int i) +{ + // note: the cosmogangs are stuck on the drive belts(5), + // and the energy crates can lock(or loosen) themselves from the belt + + if (BIT(m_cg_motor_dir, i)) { - ; + if (m_cg_motor_pos[i] > 0) + { + m_cg_motor_pos[i]--; + + // 'pull' energy crate + if (m_en_sol[i]) + m_en_motor_pos[i]--; + } + } + else + { + // 'push' energy crate + if (m_en_sol[i]) + { + if (m_en_motor_pos[i] < CG_MOTOR_LIMIT) + { + m_en_motor_pos[i]++; + m_cg_motor_pos[i]++; + } + } + + else if (m_cg_motor_pos[i] < m_en_motor_pos[i]) + m_cg_motor_pos[i]++; } - m_cg_motor_clk[N] = state; + refresh_motor_output(); +} + +TIMER_DEVICE_CALLBACK_MEMBER(cgang_state::door_motor_tick) +{ + if (m_door_motor_on & 2 && m_door_motor_pos < DOOR_MOTOR_LIMIT) + m_door_motor_pos++; + else if (m_door_motor_on & 1 && m_door_motor_pos > 0) + m_door_motor_pos--; + + refresh_motor_output(); +} + +void cgang_state::refresh_motor_output() +{ + // output motor positions in range 0-100 + for (int i = 0; i < 5; i++) + { + m_cg_count[i] = int((m_cg_motor_pos[i] / float(CG_MOTOR_LIMIT)) * 100.0 + 0.5); + m_en_count[i] = int((m_en_motor_pos[i] / float(CG_MOTOR_LIMIT)) * 100.0 + 0.5); + } + + m_door_count = int((m_door_motor_pos / float(DOOR_MOTOR_LIMIT)) * 100.0 + 0.5); } + +// maincpu (PPI1-PPI4) + READ8_MEMBER(cgang_state::ppi1_b_r) { - u8 data = 0; + u8 data = 0xff; - //data |= 0xff; + // PB0-PB4: cabinet front limit (CR1INI-CR5INI) + for (int i = 0; i < 5; i++) + if (m_en_motor_pos[i] == CG_MOTOR_LIMIT) + data ^= 1 << i; + + // PB5-PB7: cabinet back limit (HST1-HST3) + for (int i = 0; i < 3; i++) + if (m_cg_motor_pos[i] == 0) + data ^= 1 << (i + 5); return data; } READ8_MEMBER(cgang_state::ppi1_c_r) { - u8 data = 0; + u8 data = 0x7f; + + // PC0-PC1: cabinet back limit (HST4-HST5) + for (int i = 0; i < 2; i++) + if (m_cg_motor_pos[i + 3] == 0) + data ^= 1 << i; + + // PC2-PC6: cosmogang-energy crate collision (CR1-CR5) + for (int i = 0; i < 5; i++) + if (m_cg_motor_pos[i] == m_en_motor_pos[i]) + data ^= 1 << (i + 2); // PC7: audiocpu mailbox status data |= m_latch[1]->pending_r() ? 0 : 0x80; - //data |= 0x7f; - return data; } READ8_MEMBER(cgang_state::ppi2_a_r) { - u8 data = 0; + u8 data = 0x60; - // PA0-PA4: character hit lightsensors + // PA0-PA4: cosmogang hit lightsensors (G1HIT-G5HIT) for (int i = 0; i < 2; i++) { u8 mask = m_gun_lamps[i] ? 0x1f : 0; - data |= m_inputs[i + 1]->read() & mask; + data |= m_fake[i]->read() & mask; } - // PA5: gate down limit switch - // PA6: gate up limit switch - data |= 0x60; - if (m_gate_motor_pos == 0) + // lightsensors masked with SW3 + data |= ~m_dipsw[2]->read() & 0x1f; + + // PA5: door down limit switch + // PA6: door up limit switch + if (m_door_motor_pos == 0) data ^= 0x20; - else if (m_gate_motor_pos == GATE_MOTOR_LIMIT) + else if (m_door_motor_pos == DOOR_MOTOR_LIMIT) data ^= 0x40; - //data |= 0x1e; + // force door limit switches low to disable + if (~m_conf->read() & 1) + data &= ~0x60; return data; } READ8_MEMBER(cgang_state::ppi2_b_r) { - u8 data = 0; + u8 data = 0x1f; - //data |= 0xff; + // PB0-PB4: cabinet center (G1POG-G5POG) + // how this is sensed? return data; } @@ -291,8 +426,8 @@ WRITE8_MEMBER(cgang_state::ppi2_c_w) machine().bookkeeping().coin_counter_w(0, BIT(data, 0)); machine().bookkeeping().coin_lockout_w(0, BIT(~data, 1)); - // PC2: start button lamp (normal) - // PC3: start button lamp (pro) + // PC2: start button lamp (easy) + // PC3: start button lamp (hard) m_misc_lamps[0] = BIT(data, 2); m_misc_lamps[1] = BIT(data, 3); } @@ -329,25 +464,32 @@ WRITE8_MEMBER(cgang_state::ppi3_c_w) m_digits->matrix((1 << (data >> 4 & 0xf)) & 0x3ff, ls48_map[data & 0xf]); } +void cgang_state::set_en_sol(int i, int state) +{ + // put a filter on energy crate solenoids, since game keeps strobing them + if (state != (m_sol_filter[i]->param() & 1)) + m_sol_filter[i]->adjust(attotime::from_msec(1), i << 1 | state); +} + WRITE8_MEMBER(cgang_state::ppi4_a_w) { // PA2-PA4: round leds for (int i = 0; i < 3; i++) m_misc_lamps[i + 2] = BIT(data, i + 2); - // PA5-PA7: energy container solenoids (1-3) + // PA5-PA7: energy crate solenoids (1-3) for (int i = 0; i < 3; i++) - m_en_sol[i] = BIT(data, i + 5); + set_en_sol(i, BIT(data, i + 5)); } WRITE8_MEMBER(cgang_state::ppi4_b_w) { - // PB0,PB1: energy container solenoids (4-5) + // PB0,PB1: energy crate solenoids (4-5) for (int i = 0; i < 2; i++) - m_en_sol[i + 3] = BIT(data, i); + set_en_sol(i + 3, BIT(data, i)); // PB2-PB6: cosmogang solenoids - for (int i = 0; i < 2; i++) + for (int i = 0; i < 5; i++) m_cg_sol[i] = BIT(data, i + 2); // PB7: target lamp @@ -360,9 +502,12 @@ WRITE8_MEMBER(cgang_state::ppi4_c_w) for (int i = 0; i < 2; i++) m_gun_lamps[i] = BIT(~data, i); - // PC5: gate motor reverse - // PC6: gate motor - m_gate_motor_on = data >> 5 & 3; + // PC4: ticket motor + m_ticket->motor_w(BIT(data, 4)); + + // PC5: door motor reverse + // PC6: door motor + m_door_motor_on = data >> 5 & 3; // PC7: watchdog P-RUN int wd = BIT(data, 7); @@ -488,20 +633,25 @@ static INPUT_PORTS_START( cgang ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) - PORT_START("IN2") // fake inputs, indicating gun is aimed at target + PORT_START("FAKE1") // fake inputs, indicating gun is aimed at target PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 Aim Target 1") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 Aim Target 2") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 Aim Target 3") PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 Aim Target 4") PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 Aim Target 5") - PORT_START("IN3") // " + PORT_START("FAKE2") // " PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P2 Aim Target 1") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P2 Aim Target 2") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P2 Aim Target 3") PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P2 Aim Target 4") PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P2 Aim Target 5") + PORT_START("CONF1") // motorized sliding door in front of ufo entrance + PORT_CONFNAME( 0x01, 0x01, "Sliding Door System") + PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) + PORT_CONFSETTING( 0x01, DEF_STR( On ) ) + PORT_START("SW1") PORT_DIPUNKNOWN_DIPLOC( 0x01, 0x01, "SW1:1" ) PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SW1:2" ) @@ -509,36 +659,46 @@ static INPUT_PORTS_START( cgang ) PORT_START("SW2") PORT_DIPNAME( 0x03, 0x03, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW2:1,2") - PORT_DIPSETTING( 0x00, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x01, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x03, DEF_STR( 1C_1C ) ) - PORT_DIPSETTING( 0x02, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x00, DEF_STR( 3C_1C ) ) + PORT_DIPSETTING( 0x01, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x03, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x02, DEF_STR( 1C_2C ) ) PORT_DIPNAME( 0x04, 0x04, "Attract Play" ) PORT_DIPLOCATION("SW2:3") PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x04, DEF_STR( On ) ) - PORT_DIPNAME( 0x18, 0x18, "Ticket Points" ) PORT_DIPLOCATION("SW2:4,5") PORT_CONDITION("SW2", 0x20, EQUALS, 0x20) - PORT_DIPSETTING( 0x18, "5" ) - PORT_DIPSETTING( 0x10, "10" ) - PORT_DIPSETTING( 0x08, "15" ) - PORT_DIPSETTING( 0x00, "20" ) - PORT_DIPNAME( 0x18, 0x18, "Prize Points" ) PORT_DIPLOCATION("SW2:4,5") PORT_CONDITION("SW2", 0x20, EQUALS, 0x00) - PORT_DIPSETTING( 0x18, "20" ) - PORT_DIPSETTING( 0x10, "40" ) - PORT_DIPSETTING( 0x08, "60" ) - PORT_DIPSETTING( 0x00, "80" ) + PORT_DIPNAME( 0x18, 0x18, "Points per Ticket" ) PORT_DIPLOCATION("SW2:4,5") PORT_CONDITION("SW2", 0x20, EQUALS, 0x20) + PORT_DIPSETTING( 0x18, "5" ) + PORT_DIPSETTING( 0x10, "10" ) + PORT_DIPSETTING( 0x08, "15" ) + PORT_DIPSETTING( 0x00, "20" ) + PORT_DIPNAME( 0x18, 0x18, "Points per Prize" ) PORT_DIPLOCATION("SW2:4,5") PORT_CONDITION("SW2", 0x20, EQUALS, 0x00) + PORT_DIPSETTING( 0x18, "20" ) + PORT_DIPSETTING( 0x10, "40" ) + PORT_DIPSETTING( 0x08, "60" ) + PORT_DIPSETTING( 0x00, "80" ) PORT_DIPNAME( 0x20, 0x20, "Dispenser Mode" ) PORT_DIPLOCATION("SW2:6") PORT_DIPSETTING( 0x20, "Ticket" ) PORT_DIPSETTING( 0x00, "Prize" ) PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "SW2:7" ) PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW2:8" ) - PORT_START("SW3") - PORT_DIPUNKNOWN_DIPLOC( 0x01, 0x01, "SW3:1" ) - PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SW3:2" ) - PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW3:3" ) - PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW3:4" ) - PORT_DIPUNKNOWN_DIPLOC( 0x10, 0x10, "SW3:5" ) - PORT_DIPUNUSED_DIPLOC( 0x20, 0x20, "SW3:6" ) + PORT_START("SW3") // disables one of the lanes in case of hardware malfunction + PORT_DIPNAME( 0x01, 0x01, "Drive System 1" ) PORT_DIPLOCATION("SW3:1") + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x01, DEF_STR( On ) ) + PORT_DIPNAME( 0x02, 0x02, "Drive System 2" ) PORT_DIPLOCATION("SW3:2") + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x02, DEF_STR( On ) ) + PORT_DIPNAME( 0x04, 0x04, "Drive System 3" ) PORT_DIPLOCATION("SW3:3") + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x04, DEF_STR( On ) ) + PORT_DIPNAME( 0x08, 0x08, "Drive System 4" ) PORT_DIPLOCATION("SW3:4") + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x08, DEF_STR( On ) ) + PORT_DIPNAME( 0x10, 0x10, "Drive System 5" ) PORT_DIPLOCATION("SW3:5") + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x10, DEF_STR( On ) ) + PORT_DIPUNUSED_DIPLOC( 0x20, 0x20, "SW3:6" ) PORT_START("SW4") PORT_DIPNAME( 0x03, 0x02, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW4:1,2") @@ -624,7 +784,9 @@ void cgang_state::cgang(machine_config &config) WATCHDOG_TIMER(config, m_watchdog); // HA1835P m_watchdog->set_time(attotime::from_msec(100)); // approximation - TIMER(config, "gate_motor").configure_periodic(FUNC(cgang_state::gate_motor_tick), attotime::from_msec(1)); + TICKET_DISPENSER(config, m_ticket, attotime::from_msec(3000), TICKET_MOTOR_ACTIVE_HIGH, TICKET_STATUS_ACTIVE_HIGH); + + TIMER(config, "door_motor").configure_periodic(FUNC(cgang_state::door_motor_tick), attotime::from_msec(1)); /* video hardware */ PWM_DISPLAY(config, m_digits).set_size(10, 7); @@ -639,9 +801,9 @@ void cgang_state::cgang(machine_config &config) m_ymsnd->add_route(ALL_OUTPUTS, "mono", 0.50); UPD7759(config, m_adpcm[0], 640_kHz_XTAL); - m_adpcm[0]->add_route(ALL_OUTPUTS, "mono", 0.65); + m_adpcm[0]->add_route(ALL_OUTPUTS, "mono", 0.75); UPD7759(config, m_adpcm[1], 640_kHz_XTAL); - m_adpcm[1]->add_route(ALL_OUTPUTS, "mono", 0.65); + m_adpcm[1]->add_route(ALL_OUTPUTS, "mono", 0.75); } |