summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/drivers/firefox.cpp
blob: 5dc9f062f2e0d1bd470eda6bc87724b28747e3cd (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                                                  
                       


                                                                            
 


                                                        

                                                    













                                                                                                         
                                                                                      


  
                



                            
                          
                            
                            
                             
                              
                          
                             
                          
                    
 
 


                                          

                                                                                         
                                                 


                                                          
                                                      
                                            
                                              

                                                

                                                  

                                                    

                                              
                                             
           
 




                                                 


                                                    




                                                        




                                                     
                                                 



                                            



                                                 

                                                        

                                            
                                              
                                                                                                               
                                                           

                                                                          












                                                             
                                              
                                               
                                                      

                                                  

                                                              
                                              

                                                 

                                        
 


                               
                             
                          



  
                                        

 







                                                                                                                

                                            





                                                           
                         

                             




                                           
                                                  
 
                              
 
                       
                                    
                               
                                            
                               
 
                      



                               
                                                
 
                                  



                               
                                                 
 
                                                   

 
                                                     
 
                              

 
                                                     
 
                                                           

 
                                                      
 





                                                               


                        
                                                      
 
                       
                                                   


                    
                                                 
 
                             

 
 
 






                                       
                                                    
 
                                                             


 
                                       
 
                                 
                                           


 
                                 
 
                                                                                                                                                                   
                                          
                                                                   


 
                                                                                                                     
 
                   
                                                 
 
                                                         
 

                                                
                                                                                                 
                                             

                                                                            






                                                      
                                                                  
                                                         

                                                                                                      
 
                                                                                                                                                        



                         
                                                         
 


                 
                                                                 
 
                           
                                                   
 
                                                                

 
                                                                                





                                           
                                                                       

 
                                            
 
                                        
                                                     

 
                                              
 
                                          
                                                         

 
                                                   
 
                                    


 

                                      
                                


                                       
                                              
 
                                                 
 
 
                                               
 
                                                  

 
                                               
 

                                                                                       



                                       


 

                                      
                      


                                       
                                         








                                
 
                                                                                                                                        
 
 
                                          

                              
                                    

                               
                               


 

                                      



                                       
                                     
 

                                                     

 
                                    
 
                                                                                                 

 
 





                                       
                                        
 
                                           

 
                                              
 
                                                               

 
                                               
 
                                                                

 
                                          
 
                                                                      


 





                                       







                                                         


 
                                                                           

                  
                                                                         


 
                                   
 
                                                                                             
 
                                                                                                                           
 
                          




                                      
                            


                                       







                                                                                                         
                                              






                                                                                                                                  
                                                                                                                      
                                                                                                          



                                                                                                                 
                                                                                                                       



                                                                                                             
                                                                                                                     


                                                                                                               




                                      
                             


                                       




                                                                                                                 

                                                                                  





                                                                                              




                                      
                    


                                       
                                   
                           








                                                    
                           

                                                                                                                        
                                                                          





                                                     
                          





















                                                             
                          
































                                                                                     
                        
















                                       


                                                                                                     




                         
                                     

                                                           





                                      
                  


                                       
                                            

                                    

                                                                    
                                                                                
                                                                                                        
 

                                                         
 
                                                   
 



                                                                            
                                                 









                                                                                                             

                                                 

                                                                                                                  



                                                                          
 
                                     
                                                                             

                            
                                                                       
                                        
 
                                               
                                                                                      
                                                            
                                                 
 

                                                             

                                           

                                                        



                                                                           
                                                                   

                            

                                                  
 
                                              

                                                                                 

                                               
                                                       

                                                       
 
                                                       

                                                       
 
                                                       

                                                       
 
                                                       

                                                       
 
                                                         

                                                       
 
                                       

                                             
                  




                                      
                   



                                       
                                                                                            












                                                                                                                              
                                                               




                                                                                                                            
                                        

                                                                                                                            
                                                           

                      









                                                                                                                            

                                  
                                                                                           


                     
                                                                                            











                                                                                                                             
                                                               



                                                                                                                           
                                        

                                                                                                                            
                                                           

                      









                                                                                                                            

                                  
                                                                                           





                                      
                


                                       

                                                                                                                  
// license:BSD-3-Clause
// copyright-holders:smf, Aaron Giles, Chris Hardy
// thanks-to:Scott Waye
/***************************************************************************

    Atari Fire Fox hardware

    driver by smf, Aaron Giles, Chris Hardy & Scott Waye

short term:
    split driver/vidhrdw/sndhrdw/machine
    add option to centre joystick to enter test menu

it uses a quad pokey package 137323-1221-406???
the laser disc is a philips lvp 22vp931
( but maybe this works too... Special Drive: Laser Disc Player - Philips VP-832A )


AV# 60626
Atari "Firefox" V

Laser Disc - 30 minutes - Color - 1983

An interactive CAV laserdisc designed for use in the Atari video arcade game machine.
Contains over 100 visual and sound segments that include all of the branching possibilities of this game.
Each segment is two to five seconds long. This disc will play on any player,
but requires a special level III player for proper control. Video: CAV. Audio: Analog.

*/

#include "emu.h"
#include "cpu/m6809/m6809.h"
#include "cpu/m6502/m6502.h"
#include "sound/pokey.h"
#include "sound/tms5220.h"
#include "machine/74259.h"
#include "machine/adc0808.h"
#include "machine/ldvp931.h"
#include "machine/6532riot.h"
#include "machine/gen_latch.h"
#include "machine/timer.h"
#include "machine/watchdog.h"
#include "machine/x2212.h"
#include "speaker.h"


class firefox_state : public driver_device
{
public:
	firefox_state(const machine_config &mconfig, device_type type, const char *tag) :
		driver_device(mconfig, type, tag),
		m_laserdisc(*this, "laserdisc") ,
		m_tileram(*this, "tileram"),
		m_spriteram(*this, "spriteram"),
		m_sprite_palette(*this, "sprite_palette"),
		m_tile_palette(*this, "tile_palette"),
		m_maincpu(*this, "maincpu"),
		m_audiocpu(*this, "audiocpu"),
		m_gfxdecode(*this, "gfxdecode"),
		m_screen(*this, "screen"),
		m_palette(*this, "palette"),
		m_soundlatch(*this, "soundlatch"),
		m_soundlatch2(*this, "soundlatch2"),
		m_tms(*this, "tms"),
		m_nvram_1c(*this, "nvram_1c"),
		m_nvram_1d(*this, "nvram_1d"),
		m_mainbank(*this, "mainbank")
	{ }

	DECLARE_CUSTOM_INPUT_MEMBER(mainflag_r);
	DECLARE_CUSTOM_INPUT_MEMBER(soundflag_r);
	void firefox(machine_config &config);

protected:
	DECLARE_READ8_MEMBER(firefox_disc_status_r);
	DECLARE_READ8_MEMBER(firefox_disc_data_r);
	DECLARE_WRITE8_MEMBER(firefox_disc_read_w);
	DECLARE_WRITE_LINE_MEMBER(firefox_disc_lock_w);
	DECLARE_WRITE_LINE_MEMBER(audio_enable_left_w);
	DECLARE_WRITE_LINE_MEMBER(audio_enable_right_w);
	DECLARE_WRITE_LINE_MEMBER(firefox_disc_reset_w);
	DECLARE_WRITE_LINE_MEMBER(firefox_disc_write_w);
	DECLARE_WRITE8_MEMBER(firefox_disc_data_w);
	DECLARE_WRITE8_MEMBER(tileram_w);
	DECLARE_WRITE8_MEMBER(tile_palette_w);
	DECLARE_WRITE8_MEMBER(sprite_palette_w);
	DECLARE_WRITE8_MEMBER(firefox_objram_bank_w);
	DECLARE_WRITE_LINE_MEMBER(sound_reset_w);
	DECLARE_READ8_MEMBER(adc_r);
	DECLARE_WRITE8_MEMBER(adc_select_w);
	DECLARE_WRITE8_MEMBER(nvram_w);
	DECLARE_READ8_MEMBER(nvram_r);
	DECLARE_WRITE8_MEMBER(rom_bank_w);
	DECLARE_WRITE8_MEMBER(main_irq_clear_w);
	DECLARE_WRITE8_MEMBER(main_firq_clear_w);
	DECLARE_WRITE8_MEMBER(self_reset_w);
	DECLARE_WRITE_LINE_MEMBER(coin_counter_right_w);
	DECLARE_WRITE_LINE_MEMBER(coin_counter_left_w);
	DECLARE_READ8_MEMBER(riot_porta_r);
	DECLARE_WRITE8_MEMBER(riot_porta_w);
	TILE_GET_INFO_MEMBER(bgtile_get_info);
	uint32_t screen_update_firefox(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
	TIMER_DEVICE_CALLBACK_MEMBER(video_timer_callback);
	void set_rgba( int start, int index, unsigned char *palette_ram );
	void firq_gen(phillips_22vp931_device &laserdisc, int state);

	virtual void machine_start() override;
	virtual void video_start() override;
	void audio_map(address_map &map);
	void main_map(address_map &map);

private:
	required_device<phillips_22vp931_device> m_laserdisc;
	required_shared_ptr<unsigned char> m_tileram;
	required_shared_ptr<uint8_t> m_spriteram;
	required_shared_ptr<unsigned char> m_sprite_palette;
	required_shared_ptr<unsigned char> m_tile_palette;

	required_device<cpu_device> m_maincpu;
	required_device<cpu_device> m_audiocpu;
	required_device<gfxdecode_device> m_gfxdecode;
	required_device<screen_device> m_screen;
	required_device<palette_device> m_palette;
	required_device<generic_latch_8_device> m_soundlatch;
	required_device<generic_latch_8_device> m_soundlatch2;
	required_device<tms5220_device> m_tms;
	required_device<x2212_device> m_nvram_1c;
	required_device<x2212_device> m_nvram_1d;

	required_memory_bank m_mainbank;

	int m_n_disc_lock;
	int m_n_disc_data;
	int m_n_disc_read_data;
	tilemap_t *m_bgtiles;
	int m_sprite_bank;
};



#define MASTER_XTAL     XTAL(14'318'181)


/*
fff6=firq e4a2 when dav goes active/low
fff8=irq e38f  This is through a flip-flop so goes off (high as active low) only when reset_irq is active - low.
fffa=??? e38d
fffc=??? e38d
fffe=reset e7cc
*/

/* 0x50-52 Used as a copy of the status
   0x59 = 6-length of laser disc return code
   0x53 = pointer to laser disc return
   ( LaserDiscBits & 0x80 ) != 0 when return code available
   DSKREAD = acknowledge
   ReadDiscData = return code
*/

/* FXXXXX for first field
   AXXXXX for second field */


/* 20 = DISKOPR - Active low
   40 = DISKFULL - Active low
   80 = DISKDAV - Active low data available
   */
READ8_MEMBER(firefox_state::firefox_disc_status_r)
{
	uint8_t result = 0xff;

	result ^= 0x20;
	if (!m_laserdisc->ready_r())
		result ^= 0x40;
	if (m_laserdisc->data_available_r())
		result ^= 0x80;

	return result;
}

/* 4105 - DREAD */
/* this reset RDDSK (&DSKRD) */
READ8_MEMBER(firefox_state::firefox_disc_data_r)
{
	return m_n_disc_read_data;
}

/* DISK READ ENABLE */
/* 4218 - DSKREAD, set RDDSK */
WRITE8_MEMBER(firefox_state::firefox_disc_read_w)
{
	m_n_disc_read_data = m_laserdisc->data_r();
}

WRITE_LINE_MEMBER(firefox_state::firefox_disc_lock_w)
{
	m_n_disc_lock = state;
}

WRITE_LINE_MEMBER(firefox_state::audio_enable_left_w)
{
	m_laserdisc->set_output_gain(0, state ? 1.0 : 0.0);
}

WRITE_LINE_MEMBER(firefox_state::audio_enable_right_w)
{
	m_laserdisc->set_output_gain(1, state ? 1.0 : 0.0);
}

WRITE_LINE_MEMBER(firefox_state::firefox_disc_reset_w)
{
	m_laserdisc->reset_w(state ? CLEAR_LINE : ASSERT_LINE);
}

/* active low on dbb7 */
WRITE_LINE_MEMBER(firefox_state::firefox_disc_write_w)
{
	if (state == 0)
		m_laserdisc->data_w(m_n_disc_data);
}

/* latch the data */
WRITE8_MEMBER(firefox_state::firefox_disc_data_w)
{
	m_n_disc_data = data;
}




/*************************************
 *
 *  Video
 *
 *************************************/

TILE_GET_INFO_MEMBER(firefox_state::bgtile_get_info)
{
	SET_TILE_INFO_MEMBER(0, m_tileram[tile_index], 0, 0);
}


WRITE8_MEMBER(firefox_state::tileram_w)
{
	m_tileram[offset] = data;
	m_bgtiles->mark_tile_dirty(offset);
}


void firefox_state::video_start()
{
	m_bgtiles = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(firefox_state::bgtile_get_info),this), TILEMAP_SCAN_ROWS, 8,8, 64,64);
	m_bgtiles->set_transparent_pen(0);
	m_bgtiles->set_scrolldy(m_screen->visible_area().min_y, 0);
}


uint32_t firefox_state::screen_update_firefox(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	int sprite;
	int gfxtop = screen.visible_area().min_y;

	bitmap.fill(m_palette->pen_color(256), cliprect);

	for( sprite = 0; sprite < 32; sprite++ )
	{
		uint8_t *sprite_data = m_spriteram + ( 0x200 * m_sprite_bank ) + ( sprite * 16 );
		int flags = sprite_data[ 0 ];
		int y = sprite_data[ 1 ] + ( 256 * ( ( flags >> 0 ) & 1 ) );
		int x = sprite_data[ 2 ] + ( 256 * ( ( flags >> 1 ) & 1 ) );

		if( x != 0 )
		{
			int row;

			for( row = 0; row < 8; row++ )
			{
				int color = ( flags >> 2 ) & 0x03;
				int flipy = flags & 0x10;
				int flipx = flags & 0x20;
				int code = sprite_data[ 15 - row ] + ( 256 * ( ( flags >> 6 ) & 3 ) );

				m_gfxdecode->gfx( 1 )->transpen(bitmap,cliprect, code, color, flipx, flipy, x + 8, gfxtop + 500 - y - ( row * 16 ), 0 );
			}
		}
	}

	m_bgtiles->draw(screen, bitmap, cliprect, 0, 0 );

	return 0;
}

TIMER_DEVICE_CALLBACK_MEMBER(firefox_state::video_timer_callback)
{
//  m_screen->update_now();
	m_screen->update_partial(m_screen->vpos());

	m_maincpu->set_input_line(M6809_IRQ_LINE, ASSERT_LINE );
}

void firefox_state::set_rgba( int start, int index, unsigned char *palette_ram )
{
	int r = palette_ram[ index ];
	int g = palette_ram[ index + 256 ];
	int b = palette_ram[ index + 512 ];
	int a = ( b & 3 ) * 0x55;

	m_palette->set_pen_color( start + index, rgb_t( a, r, g, b ) );
}

WRITE8_MEMBER(firefox_state::tile_palette_w)
{
	m_tile_palette[ offset ] = data;
	set_rgba( 0, offset & 0xff, m_tile_palette );
}

WRITE8_MEMBER(firefox_state::sprite_palette_w)
{
	m_sprite_palette[ offset ] = data;
	set_rgba( 256, offset & 0xff, m_sprite_palette );
}

WRITE8_MEMBER(firefox_state::firefox_objram_bank_w)
{
	m_sprite_bank = data & 0x03;
}


/*************************************
 *
 *  Main <-> sound communication
 *
 *************************************/

CUSTOM_INPUT_MEMBER(firefox_state::mainflag_r)
{
	return m_soundlatch->pending_r() ? 1 : 0;
}

CUSTOM_INPUT_MEMBER(firefox_state::soundflag_r)
{
	return m_soundlatch2->pending_r() ? 1 : 0;
}

WRITE_LINE_MEMBER(firefox_state::sound_reset_w)
{
	m_audiocpu->set_input_line(INPUT_LINE_RESET, state ? ASSERT_LINE : CLEAR_LINE);
	if (state != 0)
	{
		m_soundlatch->reset();
		m_soundlatch2->reset();
	}
}


/*************************************
 *
 *  6532 RIOT handlers
 *
 *************************************/

READ8_MEMBER(firefox_state::riot_porta_r)
{
	/* bit 7 = MAINFLAG */
	/* bit 6 = SOUNDFLAG */
	/* bit 5 = PA5 */
	/* bit 4 = TEST */
	/* bit 3 = n/c */
	/* bit 2 = TMS /ready */
	/* bit 1 = TMS /read */
	/* bit 0 = TMS /write */

	return (m_soundlatch->pending_r() ? 0x80 : 0x00) | (m_soundlatch2->pending_r() ? 0x40 : 0x00) | 0x10 | (m_tms->readyq_r() << 2);
}

WRITE8_MEMBER(firefox_state::riot_porta_w)
{
	/* handle 5220 read */
	m_tms->rsq_w((data>>1) & 1);

	/* handle 5220 write */
	m_tms->wsq_w(data & 1);
}


/*************************************
 *
 *  Non-Volatile RAM (NOVRAM)
 *
 *************************************/

WRITE8_MEMBER(firefox_state::nvram_w)
{
	m_nvram_1c->write(space, offset, data >> 4);
	m_nvram_1d->write(space, offset, data & 0xf);
}

READ8_MEMBER(firefox_state::nvram_r)
{
	return (m_nvram_1c->read(space, offset) << 4) | (m_nvram_1d->read(space, offset) & 0x0f);
}


/*************************************
 *
 *  Main cpu
 *
 *************************************/

WRITE8_MEMBER(firefox_state::rom_bank_w)
{
	m_mainbank->set_entry(data & 0x1f);
}

WRITE8_MEMBER(firefox_state::main_irq_clear_w)
{
	m_maincpu->set_input_line(M6809_IRQ_LINE, CLEAR_LINE );
}

WRITE8_MEMBER(firefox_state::main_firq_clear_w)
{
	m_maincpu->set_input_line(M6809_FIRQ_LINE, CLEAR_LINE );
}

WRITE8_MEMBER(firefox_state::self_reset_w)
{
	m_maincpu->pulse_input_line(INPUT_LINE_RESET, attotime::zero);
}


/*************************************
 *
 *  I/O
 *
 *************************************/

WRITE_LINE_MEMBER(firefox_state::coin_counter_right_w)
{
	machine().bookkeeping().coin_counter_w(0, state);
}

WRITE_LINE_MEMBER(firefox_state::coin_counter_left_w)
{
	machine().bookkeeping().coin_counter_w(1, state);
}


void firefox_state::firq_gen(phillips_22vp931_device &laserdisc, int state)
{
	if (state)
		m_maincpu->set_input_line(M6809_FIRQ_LINE, ASSERT_LINE );
}


void firefox_state::machine_start()
{
	m_mainbank->configure_entries(0, 32, memregion("maincpu")->base() + 0x10000, 0x1000);

	m_laserdisc->set_data_ready_callback(phillips_22vp931_device::data_ready_delegate(&firefox_state::firq_gen, this));

	m_sprite_bank = 0;
}


/*************************************
 *
 *  Main CPU memory handlers
 *
 *************************************/

void firefox_state::main_map(address_map &map)
{
	map(0x0000, 0x0fff).ram();
	map(0x1000, 0x1fff).ram().w(this, FUNC(firefox_state::tileram_w)).share("tileram");
	map(0x2000, 0x27ff).ram().share("spriteram");
	map(0x2800, 0x2aff).ram().w(this, FUNC(firefox_state::sprite_palette_w)).share("sprite_palette");
	map(0x2b00, 0x2b00).mirror(0x04ff).w(this, FUNC(firefox_state::firefox_objram_bank_w));
	map(0x2c00, 0x2eff).ram().w(this, FUNC(firefox_state::tile_palette_w)).share("tile_palette");
	map(0x3000, 0x3fff).bankr("mainbank");
	map(0x4000, 0x40ff).rw(this, FUNC(firefox_state::nvram_r), FUNC(firefox_state::nvram_w));                     /* NOVRAM */
	map(0x4100, 0x4100).mirror(0x00f8).portr("rdin0");            /* RDIN0 */
	map(0x4101, 0x4101).mirror(0x00f8).portr("rdin1");            /* RDIN1 */
	map(0x4102, 0x4102).mirror(0x00f8).r(this, FUNC(firefox_state::firefox_disc_status_r));   /* RDIN2 */
	map(0x4103, 0x4103).mirror(0x00f8).portr("opt0");             /* OPT0 */
	map(0x4104, 0x4104).mirror(0x00f8).portr("opt1");             /* OPT1 */
	map(0x4105, 0x4105).mirror(0x00f8).r(this, FUNC(firefox_state::firefox_disc_data_r));     /* DREAD */
	map(0x4106, 0x4106).mirror(0x00f8).r(m_soundlatch2, FUNC(generic_latch_8_device::read));         /* RDSOUND */
	map(0x4107, 0x4107).mirror(0x00f8).r("adc", FUNC(adc0808_device::data_r));               /* ADC */
	map(0x4200, 0x4200).mirror(0x0047).w(this, FUNC(firefox_state::main_irq_clear_w));       /* RSTIRQ */
	map(0x4208, 0x4208).mirror(0x0047).w(this, FUNC(firefox_state::main_firq_clear_w));      /* RSTFIRQ */
	map(0x4210, 0x4210).mirror(0x0047).w("watchdog", FUNC(watchdog_timer_device::reset_w));       /* WDCLK */
	map(0x4218, 0x4218).mirror(0x0047).w(this, FUNC(firefox_state::firefox_disc_read_w));    /* DSKREAD */
	map(0x4220, 0x4223).mirror(0x0044).w("adc", FUNC(adc0808_device::address_offset_start_w));       /* ADCSTART */
	map(0x4230, 0x4230).mirror(0x0047).w(this, FUNC(firefox_state::self_reset_w));           /* AMUCK */
	map(0x4280, 0x4287).mirror(0x0040).w("latch0", FUNC(ls259_device::write_d7));
	map(0x4288, 0x428f).mirror(0x0040).w("latch1", FUNC(ls259_device::write_d7));
	map(0x4290, 0x4290).mirror(0x0047).w(this, FUNC(firefox_state::rom_bank_w));             /* WRTREG */
	map(0x4298, 0x4298).mirror(0x0047).w(m_soundlatch, FUNC(generic_latch_8_device::write));        /* WRSOUND */
	map(0x42a0, 0x42a0).mirror(0x0047).w(this, FUNC(firefox_state::firefox_disc_data_w));    /* DSKLATCH */
	map(0x4400, 0xffff).rom();
}



/*************************************
 *
 *  Sound CPU memory handlers
 *
 *************************************/

void firefox_state::audio_map(address_map &map)
{
	map(0x0000, 0x07ff).ram();
	map(0x0800, 0x087f).mirror(0x0700).ram(); /* RIOT ram */
	map(0x0880, 0x089f).mirror(0x0760).rw("riot", FUNC(riot6532_device::read), FUNC(riot6532_device::write));
	map(0x1000, 0x1000).r(m_soundlatch, FUNC(generic_latch_8_device::read));
	map(0x1800, 0x1800).w(m_soundlatch2, FUNC(generic_latch_8_device::write));
	map(0x2000, 0x200f).rw("pokey1", FUNC(pokey_device::read), FUNC(pokey_device::write));
	map(0x2800, 0x280f).rw("pokey2", FUNC(pokey_device::read), FUNC(pokey_device::write));
	map(0x3000, 0x300f).rw("pokey3", FUNC(pokey_device::read), FUNC(pokey_device::write));
	map(0x3800, 0x380f).rw("pokey4", FUNC(pokey_device::read), FUNC(pokey_device::write));
	map(0x8000, 0xffff).rom();
}



/*************************************
 *
 *  Port definitions
 *
 *************************************/

static INPUT_PORTS_START( firefox )
	PORT_START("rdin0")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_TILT )
	PORT_SERVICE( 0x04, IP_ACTIVE_LOW )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )

	PORT_START("rdin1")
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firefox_state,mainflag_r, nullptr)
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firefox_state,soundflag_r, nullptr)
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE )
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN1 )
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN2 )

	PORT_START("opt0")
	PORT_DIPNAME(    0x03, 0x00, "Coins Per Credit" )
	PORT_DIPSETTING( 0x00, "1 Coin 1 Credit" )
	PORT_DIPSETTING( 0x01, "2 Coins 1 Credit" )
	PORT_DIPSETTING( 0x02, "3 Coins 1 Credit" )
	PORT_DIPSETTING( 0x03, "4 Coins 1 Credit" )
	PORT_DIPNAME(    0x0c, 0x00, "Right Coin" )
	PORT_DIPSETTING( 0x00, "1 Coin for 1 Coin Unit" )
	PORT_DIPSETTING( 0x04, "1 Coin for 4 Coin Units" )
	PORT_DIPSETTING( 0x08, "1 Coin for 5 Coin Units" )
	PORT_DIPSETTING( 0x0c, "1 Coin for 6 Coin Units" )
	PORT_DIPNAME(    0x10, 0x00, "Left Coin" )
	PORT_DIPSETTING( 0x00, "1 Coin for 1 Coin Unit" )
	PORT_DIPSETTING( 0x10, "1 Coin for 2 Coin Units" )
	PORT_DIPNAME(    0xe0, 0x00, "Bonus Adder" )
	PORT_DIPSETTING( 0x00, DEF_STR( None ) )
	PORT_DIPSETTING( 0x20, "1 Credit for 2 Coin Units" )
	PORT_DIPSETTING( 0xa0, "1 Credit for 3 Coin Units" )
	PORT_DIPSETTING( 0x40, "1 Credit for 4 Coin Units" )
	PORT_DIPSETTING( 0x80, "1 Credit for 5 Coin Units" )
	PORT_DIPSETTING( 0x60, "2 Credits for 4 Coin Units" )
	PORT_DIPSETTING( 0xe0, DEF_STR( Free_Play ) )

	PORT_START("opt1")
	PORT_DIPNAME( 0x01, 0x00, "Missions" )
	PORT_DIPSETTING(    0x00, "All .50" )
	PORT_DIPSETTING(    0x01, ".50 .75" )
	PORT_DIPNAME( 0x06, 0x00, DEF_STR( Difficulty ) )
	PORT_DIPSETTING(    0x00, DEF_STR( Easy ) )
	PORT_DIPSETTING(    0x02, "Moderate" )
	PORT_DIPSETTING(    0x04, DEF_STR( Hard ) )
	PORT_DIPSETTING(    0x06, DEF_STR( Hardest ) )
	PORT_DIPNAME( 0x18, 0x00, "Gas Usage" )
	PORT_DIPSETTING(    0x00, DEF_STR( Easy ) )
	PORT_DIPSETTING(    0x08, "Moderate" )
	PORT_DIPSETTING(    0x10, DEF_STR( Hard ) )
	PORT_DIPSETTING(    0x18, DEF_STR( Hardest ) )
	PORT_DIPNAME( 0x60, 0x00, "Bonus Gas" )
	PORT_DIPSETTING(    0x00, DEF_STR( Easy ) )
	PORT_DIPSETTING(    0x20, "Moderate" )
	PORT_DIPSETTING(    0x40, DEF_STR( Hard ) )
	PORT_DIPSETTING(    0x60, DEF_STR( Hardest ) )
	PORT_DIPNAME( 0x80, 0x00, "Pro Limit" )
	PORT_DIPSETTING(    0x00, "Moderate" )
	PORT_DIPSETTING(    0x80, DEF_STR( Hardest ) )

	PORT_START("PITCH")
	PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_SENSITIVITY(70) PORT_KEYDELTA(30)

	PORT_START("YAW")
	PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(30)
INPUT_PORTS_END



/*************************************
 *
 *  Graphics definitions
 *
 *************************************/

static const gfx_layout tilelayout =
{
	8,8,
	RGN_FRAC(1,1),
	4,
	{ STEP4(0,1) },
	{ STEP8(0,4) },
	{ STEP8(0,32) },
	32*8
};

static const gfx_layout spritelayout =
{
	16,16,
	RGN_FRAC(1,6),
	6,
	{ RGN_FRAC(0,6), RGN_FRAC(1,6), RGN_FRAC(2,6), RGN_FRAC(3,6), RGN_FRAC(4,6), RGN_FRAC(5,6) },
	{ STEP16(0,1) },
	{ STEP16(0,16) },
	32*8
};

static GFXDECODE_START( gfx_firefox )
	GFXDECODE_ENTRY("tiles",   0, tilelayout,   0,   1)
	GFXDECODE_ENTRY("sprites", 0, spritelayout, 256, 4)
GFXDECODE_END



/*************************************
 *
 *  Machine driver
 *
 *************************************/

MACHINE_CONFIG_START(firefox_state::firefox)

	/* basic machine hardware */
	MCFG_DEVICE_ADD("maincpu", MC6809E, MASTER_XTAL/8) // 68B09E
	MCFG_DEVICE_PROGRAM_MAP(main_map)
	/* interrupts count starting at end of VBLANK, which is 44, so add 44 */
	MCFG_TIMER_DRIVER_ADD_SCANLINE("32v", firefox_state, video_timer_callback, "screen", 96+44, 128)

	MCFG_DEVICE_ADD("audiocpu", M6502, MASTER_XTAL/8)
	MCFG_DEVICE_PROGRAM_MAP(audio_map)

	MCFG_QUANTUM_TIME(attotime::from_hz(60000))

	MCFG_DEVICE_ADD("adc", ADC0809, MASTER_XTAL/16) // nominally 900 kHz
	MCFG_ADC0808_IN0_CB(IOPORT("PITCH"))
	MCFG_ADC0808_IN1_CB(IOPORT("YAW"))

	MCFG_DEVICE_ADD("latch0", LS259, 0) // 7F
	MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(WRITELINE("nvram_1c", x2212_device, recall))   // NVRECALL
	MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE("nvram_1d", x2212_device, recall))
	MCFG_ADDRESSABLE_LATCH_Q1_OUT_CB(WRITELINE(*this, firefox_state, sound_reset_w))          // RSTSOUND
	MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(WRITELINE("nvram_1c", x2212_device, store))    // NVRSTORE
	MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE("nvram_1d", x2212_device, store))
	MCFG_ADDRESSABLE_LATCH_Q3_OUT_CB(WRITELINE(*this, firefox_state, firefox_disc_lock_w))    // LOCK
	MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(WRITELINE(*this, firefox_state, audio_enable_right_w))   // SWDSKR
	MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(WRITELINE(*this, firefox_state, audio_enable_left_w))    // SWDSKL
	MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(WRITELINE(*this, firefox_state, firefox_disc_reset_w))   // RSTDSK
	MCFG_ADDRESSABLE_LATCH_Q7_OUT_CB(WRITELINE(*this, firefox_state, firefox_disc_write_w))   // WRDSK

	MCFG_DEVICE_ADD("latch1", LS259, 0) // 1F
	MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(WRITELINE(*this, firefox_state, coin_counter_right_w))   // COIN COUNTERR
	MCFG_ADDRESSABLE_LATCH_Q1_OUT_CB(WRITELINE(*this, firefox_state, coin_counter_left_w))    // COIN COUNTERL
	MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(OUTPUT("led0")) MCFG_DEVCB_INVERT
	MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(OUTPUT("led1")) MCFG_DEVCB_INVERT
	MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(OUTPUT("led2")) MCFG_DEVCB_INVERT
	MCFG_ADDRESSABLE_LATCH_Q7_OUT_CB(OUTPUT("led3")) MCFG_DEVCB_INVERT

	MCFG_WATCHDOG_ADD("watchdog")
	MCFG_WATCHDOG_TIME_INIT(attotime::from_hz(MASTER_XTAL/8/16/16/16/16))

	/* video hardware */
	MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_firefox)
	MCFG_PALETTE_ADD("palette", 512)

	MCFG_LASERDISC_22VP931_ADD("laserdisc")
	MCFG_LASERDISC_OVERLAY_DRIVER(64*8, 525, firefox_state, screen_update_firefox)
	MCFG_LASERDISC_OVERLAY_CLIP(7*8, 53*8-1, 44, 480+44)
	MCFG_LASERDISC_OVERLAY_PALETTE("palette")

	MCFG_LASERDISC_SCREEN_ADD_NTSC("screen", "laserdisc")

	MCFG_X2212_ADD_AUTOSAVE("nvram_1c")
	MCFG_X2212_ADD_AUTOSAVE("nvram_1d")

	MCFG_DEVICE_ADD("riot", RIOT6532, MASTER_XTAL/8)
	MCFG_RIOT6532_IN_PA_CB(READ8(*this, firefox_state, riot_porta_r))
	MCFG_RIOT6532_OUT_PA_CB(WRITE8(*this, firefox_state, riot_porta_w))
	MCFG_RIOT6532_IN_PB_CB(READ8("tms", tms5220_device, status_r))
	MCFG_RIOT6532_OUT_PB_CB(WRITE8("tms", tms5220_device, data_w))
	MCFG_RIOT6532_IRQ_CB(INPUTLINE("audiocpu", M6502_IRQ_LINE))

	/* sound hardware */
	SPEAKER(config, "lspeaker").front_left();
	SPEAKER(config, "rspeaker").front_right();

	MCFG_GENERIC_LATCH_8_ADD("soundlatch")
	MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE("audiocpu", INPUT_LINE_NMI))

	MCFG_GENERIC_LATCH_8_ADD("soundlatch2")

	MCFG_DEVICE_ADD("pokey1", POKEY, MASTER_XTAL/8)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.30)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.30)

	MCFG_DEVICE_ADD("pokey2", POKEY, MASTER_XTAL/8)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.30)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.30)

	MCFG_DEVICE_ADD("pokey3", POKEY, MASTER_XTAL/8)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.30)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.30)

	MCFG_DEVICE_ADD("pokey4", POKEY, MASTER_XTAL/8)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.30)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.30)

	MCFG_DEVICE_ADD("tms", TMS5220, MASTER_XTAL/2/11)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.75)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.75)

	MCFG_DEVICE_MODIFY("laserdisc")
	MCFG_SOUND_ROUTE(0, "lspeaker", 0.50)
	MCFG_SOUND_ROUTE(1, "rspeaker", 0.50)
MACHINE_CONFIG_END



/*************************************
 *
 *  ROM definitions
 *
 *************************************/

ROM_START( firefox )
	ROM_REGION( 0x30000, "maincpu", 0 ) /* 64k for code + data & 128k for banked roms */
	ROM_LOAD( "136026.209",     0x04000, 0x4000, CRC(9f559f1b) SHA1(142d14cb5158ea77f6fc6d9bf0ce723842f345e2) ) /* 8b/c */
	ROM_LOAD( "136026.210",     0x08000, 0x4000, CRC(d769b40d) SHA1(2d354649a381f3399cb0161267bd1c36a8f2bb4b) ) /* 7b/c */
	ROM_LOAD( "136026.211",     0x0c000, 0x4000, CRC(7293ab03) SHA1(73d0d173da295ad59e431bab0a9814a71146cbc2) ) /* 6b/c */
	ROM_LOAD( "136026.201",     0x10000, 0x4000, CRC(c118547a) SHA1(4d3502cbde3116588ed944bf1750bab50e4c813c) ) /* 8a */
	/* empty 7a */
	/* empty 6a */
	/* empty 5a */
	ROM_LOAD( "136026.205",     0x20000, 0x4000, CRC(dc21677f) SHA1(576a96c1e07e1362a0a367e76dc369ee8a950144) ) /* 4a */
	ROM_LOAD( "136026.127",     0x24000, 0x2000, CRC(c0c765ab) SHA1(79f6c8c1d00684d7143b2d33a5669bdf5cd01e96) ) /* 3a */
	ROM_RELOAD( 0x26000, 0x2000 )
	/* empty 2a */
	/* empty 1a */

	ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for code */
	/* empty 4k/l */
	ROM_LOAD( "136026.128",     0x08000, 0x2000, CRC(5358d870) SHA1(e8f2983a7e612e1a050a3c0b9f19b1077de4c146) ) /* 4m */
	ROM_RELOAD( 0x0a000, 0x2000 )
	ROM_LOAD( "136026.214",     0x0c000, 0x4000, CRC(92378b78) SHA1(62c7a1fee675fa3f9125f8e208b8207f0ce28bbe) ) /* 4n */

	ROM_REGION( 0x2000, "tiles", 0 )
	ROM_LOAD( "136026.125",     0x0000,  0x2000, CRC(8a32f9f1) SHA1(f899174f55cd4a24a3be4a0f4bb44d3e8e938586) ) /* 6p */

	ROM_REGION( 0x30000, "sprites", ROMREGION_ERASE00 )
	/* empty 6c */
	/* empty 6a */
	ROM_LOAD( "136026.124",     0x08000,  0x4000, CRC(5efe0f6c) SHA1(df35fd9267d966ab379c2f78ed418f4606741b28)) /* 5c */
	ROM_LOAD( "136026.123",     0x0c000,  0x4000, CRC(dffe48b3) SHA1(559907651bb425e26a834b467959b15092d23d27)) /* 5a */
	ROM_LOAD( "136026.118",     0x10000,  0x4000, CRC(0ed4df15) SHA1(7aa599f428112fff4bfedf63fafc22f19fa66546)) /* 4c */
	ROM_LOAD( "136026.122",     0x14000,  0x4000, CRC(8e2c6616) SHA1(59cbd585028bb634034a9dfd552275bd41f01989)) /* 4a */
	ROM_LOAD( "136026.117",     0x18000,  0x4000, CRC(79129084) SHA1(4219ff7cd444ad11e4cb9f1c30ac15fe0cfc5a17)) /* 3c */
	ROM_LOAD( "136026.121",     0x1c000,  0x4000, CRC(494972d4) SHA1(fa0e24e911b233e9644d7794ba03f76bfd39aa8c)) /* 3a */
	ROM_LOAD( "136026.116",     0x20000,  0x4000, CRC(d5282d4e) SHA1(de5fdf82a615625aa77b39e035b4206216faaf9c)) /* 2c */
	ROM_LOAD( "136026.120",     0x24000,  0x4000, CRC(e1b95923) SHA1(b6d0c0af0a8f55e728cd0f4c3222745eefd57f50)) /* 2a */
	ROM_LOAD( "136026.115",     0x28000,  0x4000, CRC(861abc82) SHA1(1845888d07162ae915364a2a91294731f1c5b3bd)) /* 1c */
	ROM_LOAD( "136026.119",     0x2c000,  0x4000, CRC(959471b1) SHA1(a032209a209f51d34360d5c7ad32ec62150158d2)) /* 1a */

	DISK_REGION( "laserdisc" )
	DISK_IMAGE_READONLY( "firefox", 0, SHA1(3c4be40f55b44d0352b64c0861b6d1b650451ce7) )
ROM_END

ROM_START( firefoxa )
	ROM_REGION( 0x30000, "maincpu", 0 ) /* 64k for code + data & 128k for banked roms */
	ROM_LOAD( "136026.109",     0x04000, 0x4000, CRC(7639270c) SHA1(1b8f53c516d26aecb4478ac99783a37e5b1a107f)) /* 8b/c */
	ROM_LOAD( "136026.110",     0x08000, 0x4000, CRC(f3102944) SHA1(460f18180b19b6360c99c7e70f86d745f69ba95d)) /* 7b/c */
	ROM_LOAD( "136026.111",     0x0c000, 0x4000, CRC(8a230bb5) SHA1(0cfa1e981e4a8ccaf5903b4e761a2085b5a56181)) /* 6b/c */
	ROM_LOAD( "136026.101",     0x10000, 0x4000, CRC(91bba45a) SHA1(d584a8f60bbbdbe250978b7aeb3f5e7698f94d60)) /* 8a */
	ROM_LOAD( "136026.102",     0x14000, 0x4000, CRC(5f1e423d) SHA1(c55c27600877272c1ca94eab75c1eb25ff84d36f)) /* 7a */
	/* empty 6a */
	/* empty 5a */
	ROM_LOAD( "136026.105",     0x20000, 0x4000, CRC(83f1d4ed) SHA1(ed4b22b3473f16cbcca1415f6d81be558ab10ff3)) /* 4a */
	ROM_LOAD( "136026.106",     0x24000, 0x4000, CRC(c5d8d417) SHA1(6a29595b2c091bbcf413c7213c6577eaf9c507d1)) /* 3a */
	/* empty 2a */
	/* empty 1a */

	ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for code */
	/* empty 4k/l */
	ROM_LOAD( "136026.113",     0x08000, 0x4000, CRC(90988b3b) SHA1(7571cf6b7e9e3e22f930d9ba991b730e734edfb7)) /* 4m */
	ROM_LOAD( "136026.114",     0x0c000, 0x4000, CRC(1437ce14) SHA1(eef14172b3935a4afb3470852f93d30926b139e4)) /* 4n */

	ROM_REGION( 0x2000, "tiles", 0 )
	ROM_LOAD( "136026.125",     0x0000,  0x2000, CRC(8a32f9f1) SHA1(f899174f55cd4a24a3be4a0f4bb44d3e8e938586) ) /* 6p */

	ROM_REGION( 0x30000, "sprites", ROMREGION_ERASE00 )
	/* empty 6c */
	/* empty 6a */
	ROM_LOAD( "136026.124",     0x08000,  0x4000, CRC(5efe0f6c) SHA1(df35fd9267d966ab379c2f78ed418f4606741b28)) /* 5c */
	ROM_LOAD( "136026.123",     0x0c000,  0x4000, CRC(dffe48b3) SHA1(559907651bb425e26a834b467959b15092d23d27)) /* 5a */
	ROM_LOAD( "136026.118",     0x10000,  0x4000, CRC(0ed4df15) SHA1(7aa599f428112fff4bfedf63fafc22f19fa66546)) /* 4c */
	ROM_LOAD( "136026.122",     0x14000,  0x4000, CRC(8e2c6616) SHA1(59cbd585028bb634034a9dfd552275bd41f01989)) /* 4a */
	ROM_LOAD( "136026.117",     0x18000,  0x4000, CRC(79129084) SHA1(4219ff7cd444ad11e4cb9f1c30ac15fe0cfc5a17)) /* 3c */
	ROM_LOAD( "136026.121",     0x1c000,  0x4000, CRC(494972d4) SHA1(fa0e24e911b233e9644d7794ba03f76bfd39aa8c)) /* 3a */
	ROM_LOAD( "136026.116",     0x20000,  0x4000, CRC(d5282d4e) SHA1(de5fdf82a615625aa77b39e035b4206216faaf9c)) /* 2c */
	ROM_LOAD( "136026.120",     0x24000,  0x4000, CRC(e1b95923) SHA1(b6d0c0af0a8f55e728cd0f4c3222745eefd57f50)) /* 2a */
	ROM_LOAD( "136026.115",     0x28000,  0x4000, CRC(861abc82) SHA1(1845888d07162ae915364a2a91294731f1c5b3bd)) /* 1c */
	ROM_LOAD( "136026.119",     0x2c000,  0x4000, CRC(959471b1) SHA1(a032209a209f51d34360d5c7ad32ec62150158d2)) /* 1a */

	DISK_REGION( "laserdisc" )
	DISK_IMAGE_READONLY( "firefox", 0, SHA1(3c4be40f55b44d0352b64c0861b6d1b650451ce7) )
ROM_END



/*************************************
 *
 *  Game drivers
 *
 *************************************/

GAME( 1984, firefox,  0,       firefox, firefox, firefox_state, empty_init, ROT0, "Atari", "Fire Fox (set 1)", 0 )
GAME( 1984, firefoxa, firefox, firefox, firefox, firefox_state, empty_init, ROT0, "Atari", "Fire Fox (set 2)", 0 )