summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/drivers/wacky_gator.cpp
blob: f95c135a59dc95615a292fd5861b41b8f9e2b7a1 (plain) (tree)
1
2
3
4
5
6
7
                   
                                                


              

                                                         





                                                                                                            


                                          



                            


                            
                          
                          

                         
 


                      


                                           

                                                                                          




                                                


                                                      
                                            

           



                                                                
 


                                              
 
                                             


                                                  
 
                                             
                                              
                                                                                                      
 
                                              
                                                                                         

                                          
                                                                                               



                                                                                                               
                                                                                                                    
 
                                           
 
        







                                                          
                                  
 
                            

                               
 
                                    
                                


  










                                             
                                                                
                                        























                                                 
                                                                       












                                                 

 








                                                                         
                                                 
         

 







                                                              

 






                                                                                    

 



                                    
                          







                                           




                                    

 
                                                     
 


                                                                                                                                               

 
                                                    
 
                               
                                               


                                    
                         
                                                                                                                                      




                                                   
                                                                                                                                        
























                                                                                                                          


                                            
 
                                   
         
                                                                       


                                                                         
         

 





















                                                                                                     
 
                                              
 


                                                                                       

                                                                                                                
 
                   
                                            
 
                   
                                               

                                                                                             
                                                                         
                                                  
 
                                                          


                                                  


                                                                                  

                                            


                                                                                 






                                                
                                                                 
                                                                                    
                                                                 
                                                                                    
                                                                 
                                                                                    

                                                
                                                                 
                                                                        
                                                                 
                                                                                    
                                                                 
                                                                                    

                                                                                                                          



                     

                                                                                                            
 

                                                                                                             

       
                                                                                                                                                                         
// license:GPL-2.0+
// copyright-holders:FelipeSanches, Sandro Ronco
//
// Wacky Gator
//
// Driver by Sandro Ronco and
//  Felipe Correa da Silva Sanches <juca@members.fsf.org>
//

/*
   Most of this driver is based on guessing since I do not have access to the actual pcb for this game.
   Once we get a pcb, please review the correctness of the code in this driver before deleting this comment.

   TODO:
   - IRQ and NMI sources are unknown
   - proper PMM8713 and steppers emulation
*/

#include "emu.h"
#include "cpu/m6809/m6809.h"
#include "machine/i8255.h"
#include "machine/pit8253.h"
#include "machine/ticket.h"
#include "machine/timer.h"
#include "sound/msm5205.h"
#include "sound/ym2413.h"
#include "speaker.h"

#include "wackygtr.lh"


class wackygtr_state : public driver_device
{
public:
	wackygtr_state(const machine_config &mconfig, device_type type, const char *tag) :
		driver_device(mconfig, type, tag),
		m_maincpu(*this, "maincpu"),
		m_msm(*this, "msm"),
		m_pit8253_0(*this, "pit8253_0"),
		m_pit8253_1(*this, "pit8253_1"),
		m_ticket(*this, "ticket"),
		m_samples(*this, "oki"),
		m_alligator(*this, "alligator%u", 0U),
		m_digit(*this, "digit%u", 0U),
		m_lamps(*this, "lamp%u", 0U)
	{ }

	DECLARE_CUSTOM_INPUT_MEMBER(alligators_rear_sensors_r);
	DECLARE_CUSTOM_INPUT_MEMBER(alligators_front_sensors_r);

	void wackygtr(machine_config &config);

protected:
	virtual void machine_start() override;
	virtual void machine_reset() override;

	DECLARE_WRITE_LINE_MEMBER(adpcm_int);
	DECLARE_WRITE8_MEMBER(sample_ctrl_w);
	DECLARE_WRITE8_MEMBER(alligators_ctrl1_w);
	DECLARE_WRITE8_MEMBER(alligators_ctrl2_w);

	void set_lamps(int p, uint8_t value);
	DECLARE_WRITE8_MEMBER(status_lamps_w);
	template <unsigned N> DECLARE_WRITE8_MEMBER(timing_lamps_w) { set_lamps((N + 1) << 3, data); }

	void set_digits(int p, uint8_t value);
	template <unsigned N> DECLARE_WRITE8_MEMBER(disp_w) { set_digits(N << 1, data); }

	void pmm8713_ck(int i, int state);
	template <unsigned N> DECLARE_WRITE_LINE_MEMBER(alligator_ck) { pmm8713_ck(N, state); }

	DECLARE_WRITE8_MEMBER(irq_ack_w)            { m_maincpu->set_input_line(M6809_IRQ_LINE, CLEAR_LINE); }
	DECLARE_WRITE8_MEMBER(firq_ack_w)           { m_maincpu->set_input_line(M6809_FIRQ_LINE, CLEAR_LINE); }

	TIMER_DEVICE_CALLBACK_MEMBER(nmi_timer)     { m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); }

	void program_map(address_map &map);

private:
	required_device<cpu_device> m_maincpu;
	required_device<msm5205_device> m_msm;
	required_device<pit8253_device> m_pit8253_0;
	required_device<pit8253_device> m_pit8253_1;
	required_device<ticket_dispenser_device> m_ticket;
	required_memory_region m_samples;
	output_finder<5> m_alligator;
	output_finder<8> m_digit;
	output_finder<32> m_lamps;

	int     m_adpcm_sel;
	uint16_t  m_adpcm_pos;
	uint8_t   m_adpcm_ctrl;

	uint8_t   m_alligators_ctrl;
	int     m_motors_pos[5];
};


WRITE8_MEMBER(wackygtr_state::status_lamps_w)
{
	/*
	    ---x xxxx   status lamps
	    --x- ----   game over lamp
	    -x-- ----   coin counter
	    x--- ----   ticket dispenser
	*/

	set_lamps(0, data & 0x3f);

	machine().bookkeeping().coin_counter_w(0, BIT(data, 6));
	m_ticket->motor_w(BIT(data, 7));
}

WRITE8_MEMBER(wackygtr_state::sample_ctrl_w)
{
	/*
	    --xx xxxx    sample index
	    -x-- ----    ???
	    x--- ----    5205 reset
	*/

	m_adpcm_ctrl = data;
	m_adpcm_pos = (data & 0x3f) * 0x400;
	m_adpcm_sel = 0;
	m_msm->reset_w(BIT(data, 7));
}

WRITE8_MEMBER(wackygtr_state::alligators_ctrl1_w)
{
	m_pit8253_0->write_gate0(BIT(data, 0));
	m_pit8253_0->write_gate1(BIT(data, 1));
	m_pit8253_0->write_gate2(BIT(data, 2));
	m_pit8253_1->write_gate1(BIT(data, 3));
	m_pit8253_1->write_gate2(BIT(data, 4));

	machine().bookkeeping().coin_lockout_w(0, data & 0x40 ? 0 : 1);
}

WRITE8_MEMBER(wackygtr_state::alligators_ctrl2_w)
{
	/*
	    ---- ---x    PMM8713 0 U/D
	    ---- --x-    PMM8713 1 U/D
	    ---- -x--    PMM8713 2 U/D
	    ---- x---    PMM8713 3 U/D
	    ---x ----    PMM8713 4 U/D
	*/

	m_alligators_ctrl = data & 0x1f;
}

void wackygtr_state::pmm8713_ck(int i, int state)
{
	if (state)
	{
		m_motors_pos[i] += (BIT(m_alligators_ctrl, i) ? +1 : -1);

		int alligator_state = m_motors_pos[i] / 10;
		if (alligator_state > 5)    alligator_state = 5;
		if (alligator_state < 0)    alligator_state = 0;
		m_alligator[i] = alligator_state;
	}
}

CUSTOM_INPUT_MEMBER(wackygtr_state::alligators_rear_sensors_r)
{
	return  ((m_motors_pos[0] < 10) ? 0x01 : 0) |
			((m_motors_pos[1] < 10) ? 0x02 : 0) |
			((m_motors_pos[2] < 10) ? 0x04 : 0) |
			((m_motors_pos[3] < 10) ? 0x08 : 0) |
			((m_motors_pos[4] < 10) ? 0x10 : 0) |
			(m_alligators_ctrl ^ 0x1f);
}

CUSTOM_INPUT_MEMBER(wackygtr_state::alligators_front_sensors_r)
{
	return  ((m_motors_pos[0] < 5 || m_motors_pos[0] > 55) ? 0x01 : 0) |
			((m_motors_pos[1] < 5 || m_motors_pos[1] > 55) ? 0x02 : 0) |
			((m_motors_pos[2] < 5 || m_motors_pos[2] > 55) ? 0x04 : 0) |
			((m_motors_pos[3] < 5 || m_motors_pos[3] > 55) ? 0x08 : 0) |
			((m_motors_pos[4] < 5 || m_motors_pos[4] > 55) ? 0x10 : 0);
}

void wackygtr_state::machine_start()
{
	m_alligator.resolve();
	m_digit.resolve();
	m_lamps.resolve();

	save_item(NAME(m_adpcm_sel));
	save_item(NAME(m_adpcm_pos));
	save_item(NAME(m_adpcm_ctrl));
	save_item(NAME(m_alligators_ctrl));
	save_item(NAME(m_motors_pos));
}

void wackygtr_state::machine_reset()
{
	m_adpcm_pos = 0;
	m_adpcm_sel = 0;
	m_adpcm_ctrl = 0x80;
}

void wackygtr_state::set_digits(int p, uint8_t value)
{
	static constexpr uint8_t bcd2hex[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x67, 0, 0, 0, 0, 0, 0 };  // not accurate
	m_digit[p + 0] = bcd2hex[value & 0x0f];
	m_digit[p + 1] = bcd2hex[(value >> 4) & 0x0f];
}

void wackygtr_state::set_lamps(int p, uint8_t value)
{
	for (int i=0; i<8; i++)
		m_lamps[p + i] = BIT(value, i);
}

static INPUT_PORTS_START( wackygtr )
	PORT_START("IN0")
	PORT_BIT(0x1f, IP_ACTIVE_LOW, IPT_CUSTOM)  PORT_CUSTOM_MEMBER(DEVICE_SELF, wackygtr_state, alligators_rear_sensors_r, nullptr)
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_SERVICE)
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_SERVICE1)
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_COIN1)

	PORT_START("IN1")
	PORT_BIT(0x1f, IP_ACTIVE_LOW, IPT_CUSTOM)   PORT_CUSTOM_MEMBER(DEVICE_SELF, wackygtr_state, alligators_front_sensors_r, nullptr)
	PORT_DIPNAME( 0xe0, 0x00, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW:1,2,3")
	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(    0x20, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(    0x40, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(    0x60, DEF_STR( 2C_1C ) )
	PORT_DIPSETTING(    0x80, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(    0xa0, DEF_STR( 2C_1C ) )
	PORT_DIPSETTING(    0xc0, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(    0xe0, DEF_STR( 2C_1C ) )

	PORT_START("IN2")
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_POKER_HOLD1)
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_POKER_HOLD2)
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_POKER_HOLD3)
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_POKER_HOLD4)
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD5)
	PORT_DIPNAME( 0x20, 0x20, DEF_STR( Test ) ) PORT_DIPLOCATION("SW:4")   // For factory Test use ONLY! Do not change
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
	PORT_DIPNAME( 0x40, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW:5")
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
	PORT_DIPNAME( 0x80, 0x80, DEF_STR( Test ) ) PORT_DIPLOCATION("SW:6")   // For factory Test use ONLY! Do not change
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
INPUT_PORTS_END

WRITE_LINE_MEMBER(wackygtr_state::adpcm_int)
{
	if (!(m_adpcm_ctrl & 0x80))
	{
		uint8_t data = m_samples->base()[m_adpcm_pos & 0xffff];
		m_msm->data_w((m_adpcm_sel ? data : (data >> 4)) & 0x0f);
		m_adpcm_pos += m_adpcm_sel;
		m_adpcm_sel ^= 1;
	}
}

void wackygtr_state::program_map(address_map &map)
{
	map(0x0200, 0x0200).nopr().w(this, FUNC(wackygtr_state::irq_ack_w));
	map(0x0400, 0x0400).nopr().w(this, FUNC(wackygtr_state::firq_ack_w));
	map(0x0600, 0x0600).w(this, FUNC(wackygtr_state::disp_w<0>));
	map(0x0800, 0x0800).w(this, FUNC(wackygtr_state::disp_w<1>));
	map(0x0a00, 0x0a00).w(this, FUNC(wackygtr_state::disp_w<2>));
	map(0x0c00, 0x0c00).w(this, FUNC(wackygtr_state::disp_w<3>));
	map(0x0e00, 0x0e00).w(this, FUNC(wackygtr_state::sample_ctrl_w));

	map(0x1000, 0x1001).w("ymsnd", FUNC(ym2413_device::write));

	map(0x2000, 0x2003).rw(m_pit8253_0, FUNC(pit8253_device::read), FUNC(pit8253_device::write));
	map(0x3000, 0x3003).rw(m_pit8253_1, FUNC(pit8253_device::read), FUNC(pit8253_device::write));

	map(0x4000, 0x4003).rw("i8255_0", FUNC(i8255_device::read), FUNC(i8255_device::write));
	map(0x5000, 0x5003).rw("i8255_1", FUNC(i8255_device::read), FUNC(i8255_device::write));
	map(0x6000, 0x6003).rw("i8255_2", FUNC(i8255_device::read), FUNC(i8255_device::write));

	map(0x7000, 0x7fff).ram();
	map(0x8000, 0xffff).rom();
}

MACHINE_CONFIG_START(wackygtr_state::wackygtr)

	MCFG_DEVICE_ADD("maincpu", MC6809, XTAL(3'579'545))   // HD68B09P
	MCFG_DEVICE_PROGRAM_MAP(program_map)
	MCFG_DEVICE_PERIODIC_INT_DRIVER(wackygtr_state, irq0_line_assert, 50)  // FIXME

	MCFG_TIMER_DRIVER_ADD_PERIODIC("nmi_timer", wackygtr_state, nmi_timer, attotime::from_hz(100))  // FIXME

	/* Video */
	MCFG_DEFAULT_LAYOUT(layout_wackygtr)

	/* Sound */
	SPEAKER(config, "mono").front_center();
	MCFG_DEVICE_ADD("msm", MSM5205, XTAL(384'000) )
	MCFG_MSM5205_VCLK_CB(WRITELINE(*this, wackygtr_state, adpcm_int))   /* IRQ handler */
	MCFG_MSM5205_PRESCALER_SELECTOR(S48_4B)      /* 8 KHz, 4 Bits  */
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)

	MCFG_DEVICE_ADD("ymsnd", YM2413, XTAL(3'579'545) )
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)

	MCFG_DEVICE_ADD("i8255_0", I8255, 0)
	MCFG_I8255_OUT_PORTA_CB(WRITE8(*this, wackygtr_state, status_lamps_w))
	MCFG_I8255_OUT_PORTB_CB(WRITE8(*this, wackygtr_state, alligators_ctrl1_w))
	MCFG_I8255_OUT_PORTC_CB(WRITE8(*this, wackygtr_state, alligators_ctrl2_w))

	MCFG_DEVICE_ADD("i8255_1", I8255, 0)
	MCFG_I8255_OUT_PORTA_CB(WRITE8(*this, wackygtr_state, timing_lamps_w<0>))
	MCFG_I8255_OUT_PORTB_CB(WRITE8(*this, wackygtr_state, timing_lamps_w<1>))
	MCFG_I8255_OUT_PORTC_CB(WRITE8(*this, wackygtr_state, timing_lamps_w<2>))

	MCFG_DEVICE_ADD("i8255_2", I8255, 0)
	MCFG_I8255_IN_PORTA_CB(IOPORT("IN0"))
	MCFG_I8255_IN_PORTB_CB(IOPORT("IN1"))
	MCFG_I8255_IN_PORTC_CB(IOPORT("IN2"))

	MCFG_DEVICE_ADD("pit8253_0", PIT8253, 0)
	MCFG_PIT8253_CLK0(XTAL(3'579'545)/16)  // this is a guess
	MCFG_PIT8253_OUT0_HANDLER(WRITELINE(*this, wackygtr_state, alligator_ck<0>))
	MCFG_PIT8253_CLK1(XTAL(3'579'545)/16)  // this is a guess
	MCFG_PIT8253_OUT1_HANDLER(WRITELINE(*this, wackygtr_state, alligator_ck<1>))
	MCFG_PIT8253_CLK2(XTAL(3'579'545)/16)  // this is a guess
	MCFG_PIT8253_OUT2_HANDLER(WRITELINE(*this, wackygtr_state, alligator_ck<2>))

	MCFG_DEVICE_ADD("pit8253_1", PIT8253, 0)
	MCFG_PIT8253_CLK0(XTAL(3'579'545)/16)  // this is a guess
	MCFG_PIT8253_OUT0_HANDLER(INPUTLINE("maincpu", M6809_FIRQ_LINE))
	MCFG_PIT8253_CLK1(XTAL(3'579'545)/16)  // this is a guess
	MCFG_PIT8253_OUT1_HANDLER(WRITELINE(*this, wackygtr_state, alligator_ck<3>))
	MCFG_PIT8253_CLK2(XTAL(3'579'545)/16)  // this is a guess
	MCFG_PIT8253_OUT2_HANDLER(WRITELINE(*this, wackygtr_state, alligator_ck<4>))

	MCFG_TICKET_DISPENSER_ADD("ticket", attotime::from_msec(200), TICKET_MOTOR_ACTIVE_HIGH, TICKET_STATUS_ACTIVE_HIGH)
MACHINE_CONFIG_END


ROM_START( wackygtr )
	ROM_REGION(0x10000, "maincpu", 0)
	ROM_LOAD("wp3-pr0.4d", 0x8000, 0x8000, CRC(71ca4437) SHA1(c7d948c5593e6053fd0a65601f6c06871f5861f0))

	ROM_REGION(0x10000, "oki", 0)
	ROM_LOAD("wp3-vo0.2h", 0x0000, 0x10000, CRC(91c7986f) SHA1(bc9fa0d41c1caa0f909a349f511d022b7e42c6cd))
ROM_END

GAME(1990, wackygtr,    0, wackygtr,  wackygtr, wackygtr_state, empty_init, ROT0, "Data East", "Wacky Gator", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_CLICKABLE_ARTWORK)