summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/sound/st0016.cpp
blob: d2f0653364a94ae57cbf01ce9d4bba32f29a4a29 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                       
                                                              




                                                                      
                

                   

                     
 
 
                         
                                                                          
 
 


                                                                            
 



                                                   
                                                                                                             






                                                      
 
                                                           

 
 





                                                   
                                             
                                      
 



                                  

 





                                                                                                                               
 

                            


                             

                                           
                                                 


                               
                                                        










                                                                            
                                                              
                         
                                                                                           



                                                                            


                                                             

                                                           
                                                

                                                                                                   
                                                                        
                                         
                                                                           




                                                                           
                                                                       
                                         
                                                                                
                                                 

                                                                                   



                                                                       
                                                                                  







                                                 
                                     





                                             
 
                                           
 
                              

 
                                            
 



                                    
 
                              
 




                                                                            
 
                                                                                             




                                                                                                 
                                                    

                 
 
// license:BSD-3-Clause
// copyright-holders:R. Belmont, Tomasz Slanina, David Haywood
/************************************
      Seta custom ST-0016 chip
      sound emulation by R. Belmont, Tomasz Slanina, and David Haywood
************************************/

#include "emu.h"
#include "st0016.h"

//#define VERBOSE 1
#include "logmacro.h"


// device type definition
DEFINE_DEVICE_TYPE(ST0016, st0016_device, "st0016", "Seta ST0016 (Audio)")


//**************************************************************************
//  LIVE DEVICE
//**************************************************************************

//-------------------------------------------------
//  st0016_device - constructor
//-------------------------------------------------

st0016_device::st0016_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, ST0016, tag, owner, clock)
	, device_sound_interface(mconfig, *this)
	, m_stream(nullptr)
	, m_ram_read_cb(*this)
	, m_vpos{ 0, 0, 0, 0, 0, 0, 0, 0 }
	, m_frac{ 0, 0, 0, 0, 0, 0, 0, 0 }
	, m_lponce{ 0, 0, 0, 0, 0, 0, 0, 0 }
{
	std::fill(std::begin(m_regs), std::end(m_regs), 0);
}


//-------------------------------------------------
//  device_start - device-specific startup
//-------------------------------------------------

void st0016_device::device_start()
{
	m_stream = stream_alloc(0, 2, 44100);
	m_ram_read_cb.resolve_safe(0);

	save_item(NAME(m_vpos));
	save_item(NAME(m_frac));
	save_item(NAME(m_lponce));
	save_item(NAME(m_regs));
}


//-------------------------------------------------
//  sound_stream_update - handle a stream update
//-------------------------------------------------

void st0016_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
	int v, i, snum;
	unsigned char *slot;
	int32_t mix[48000*2];
	int32_t *mixp;
	int16_t sample;
	int sptr, eptr, freq, lsptr, leptr;

	memset(mix, 0, sizeof(mix[0])*samples*2);

	for (v = 0; v < 8; v++)
	{
		slot = (unsigned char *)&m_regs[v * 32];

		if (slot[0x16] & 0x06)
		{
			mixp = &mix[0];

			sptr = slot[0x02]<<16 | slot[0x01]<<8 | slot[0x00];
			eptr = slot[0x0e]<<16 | slot[0x0d]<<8 | slot[0x0c];
			freq = slot[0x11]<<8 | slot[0x10];
			lsptr = slot[0x06]<<16 | slot[0x05]<<8 | slot[0x04];
			leptr = slot[0x0a]<<16 | slot[0x09]<<8 | slot[0x08];

			for (snum = 0; snum < samples; snum++)
			{
				sample = m_ram_read_cb((sptr + m_vpos[v]) & 0x1fffff) << 8;

				*mixp++ += (sample * (char)slot[0x14]) >> 8;
				*mixp++ += (sample * (char)slot[0x15]) >> 8;

				m_frac[v] += freq;
				m_vpos[v] += (m_frac[v]>>16);
				m_frac[v] &= 0xffff;

				// stop if we're at the end
				if (m_lponce[v])
				{
					// we've looped once, check loop end rather than sample end
					if ((m_vpos[v] + sptr) >= leptr)
					{
						m_vpos[v] = (lsptr - sptr);
					}
				}
				else
				{
					// not looped yet, check sample end
					if ((m_vpos[v] + sptr) >= eptr)
					{
						if (slot[0x16] & 0x01)  // loop?
						{
							m_vpos[v] = (lsptr - sptr);
							m_lponce[v] = 1;
						}
						else
						{
							slot[0x16] = 0;
							m_vpos[v] = m_frac[v] = 0;
						}
					}
				}
			}
		}
	}

	mixp = &mix[0];
	for (i = 0; i < samples; i++)
	{
		outputs[0][i] = (*mixp++)>>4;
		outputs[1][i] = (*mixp++)>>4;
	}
}


READ8_MEMBER( st0016_device::st0016_snd_r )
{
	return m_regs[offset];
}

WRITE8_MEMBER( st0016_device::st0016_snd_w )
{
	int voice = offset/32;
	int reg = offset & 0x1f;
	int oldreg = m_regs[offset];
	int vbase = offset & ~0x1f;

	m_regs[offset] = data;

	if ((voice < 8) && (data != oldreg))
	{
		if ((reg == 0x16) && (data != 0))
		{
			m_vpos[voice] = m_frac[voice] = m_lponce[voice] = 0;

			LOG("Key on V%02d: st %06x-%06x lp %06x-%06x frq %x flg %x\n", voice,
				m_regs[vbase+2]<<16   | m_regs[vbase+1]<<8   | m_regs[vbase+2],
				m_regs[vbase+0xe]<<16 | m_regs[vbase+0xd]<<8 | m_regs[vbase+0xc],
				m_regs[vbase+6]<<16   | m_regs[vbase+5]<<8   | m_regs[vbase+4],
				m_regs[vbase+0xa]<<16 | m_regs[vbase+0x9]<<8 | m_regs[vbase+0x8],
				m_regs[vbase+0x11]<<8 | m_regs[vbase+0x10],
				m_regs[vbase+0x16]);
		}
	}
}