summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/audio/targ.cpp
blob: d83b665955fe4017e15217385e3f5d4236e3812a (plain) (tree)
1
2
3
4
5

                                

                                                                          
                 









                                                                          
                
                           
                           
                    
 
 
 

                                  
 
                                    
 
                                                                                                                                                              
                                                                                                                                                      

  
 
                                                      

                                                                   
 
 
                                             
 
                           
 




                                                                   
 

                                                           

            

                                                                                     

         
 
 
                                            

                       

                                           

                  
                                                                                 
                                                     


                              
         
                                
                                              

                                              



                        
                                   
            
         
                                                            

                                        
                                                           
                            
                                                           
                 
         



                                          

                                   
 
                                           


                              
                                
 
                             

 
 
                                            
 
                                                     
         
                                                          
 
                                                             
 
                                                                           

         
                             

 
 
                                               
 
                            

 



                                         




                 
               


  
 
                                              
 
                          
 

                          
 






                                                                                        
 



                                       


 
                                                         
 
                                            


 
                                                      
 
                                         
 
                           
 
                                        


 

                                                       
                                                  
 




                                                                                      
 

                                                                             

                                                          
 

                                                    
                                                  
 




                                                                                   
 

                                                                             

                                                          
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/*************************************************************************

    Targ hardware

*************************************************************************/

/* Sound channel usage
   0 = CPU music,  Shoot
   1 = Crash
   2 = Spectar sound
   3 = Tone generator
*/

#include "emu.h"
#include "includes/exidy.h"
#include "sound/volt_reg.h"
#include "speaker.h"



#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,
	-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)
{
	m_tone_freq = freq;

	if (!m_samples->playing(3))
	{
		m_samples->set_volume(3, 0);
		m_samples->start_raw(3, sine_wave, 32, 1000, true);
	}

	if ((m_tone_freq == 0xff) || (m_tone_freq == 0x00))
		m_samples->set_volume(3, 0);
	else
	{
		m_samples->set_frequency(3, 1.0 * m_max_freq / (0xff - m_tone_freq));
		m_samples->set_volume(3, m_tone_active);
	}
}


WRITE8_MEMBER( exidy_state::targ_audio_1_w )
{
	/* 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);

	/* crash */
	if (RISING_EDGE(0x20))
	{
		if (data & 0x40)
			m_samples->start(1,0);
		else
			m_samples->start(1,2);
	}

	/* Sspec */
	if (data & 0x10)
		m_samples->stop(2);
	else
	{
		if ((data & 0x08) != (m_port_1_last & 0x08))
		{
			if (data & 0x08)
				m_samples->start(2,3,true);
			else
				m_samples->start(2,4,true);
		}
	}

	/* Game (tone generator enable) */
	if (FALLING_EDGE(0x80))
	{
		m_tone_pointer = 0;
		m_tone_active = 0;

		adjust_sample(m_tone_freq);
	}

	if (RISING_EDGE(0x80))
		m_tone_active=1;

	m_port_1_last = data;
}


WRITE8_MEMBER( exidy_state::targ_audio_2_w )
{
	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;
}


WRITE8_MEMBER( exidy_state::spectar_audio_2_w )
{
	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)
{
	common_audio_start(TARG_MAXFREQ);

	m_tone_pointer = 0;

	save_item(NAME(m_tone_pointer));
}


void exidy_state::spectar_audio(machine_config &config)
{
	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);
	voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref", 0));
	vref.add_route(0, "dac", 1.0, DAC_VREF_POS_INPUT);
}

void exidy_state::targ_audio(machine_config &config)
{
	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::targ_audio_start));
	m_samples->add_route(ALL_OUTPUTS, "speaker", 0.25);

	DAC_1BIT(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.99);
	voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref", 0));
	vref.add_route(0, "dac", 1.0, DAC_VREF_POS_INPUT);
}