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

	audio/pc.c

	Functions to emulate a PC PIC timer 2 used for simple tone generation

	TODO:
	Add support for the SN76496 used in the Tandy1000/PCjr
	It most probably is on port 0xc0, but I'm not sure...

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

#include "driver.h"
#include "streams.h"
#include "machine/pcshare.h"
#include "machine/pit8253.h"
#include "audio/pc.h"

#define SND_LOG(n,m,a)
#define BASECLOCK	1193180


static void *pc_sh_custom_start(int clock, const struct CustomSound_interface *config);

const struct CustomSound_interface pc_sound_interface =
{
	pc_sh_custom_start
};

static sound_stream *channel;
static int speaker_gate = 0;



/*************************************
 *
 *	Sound handler start
 *
 *************************************/

static int pc_sh_start(void)
{
	logerror("pc_sh_start\n");
	channel = stream_create(0, 1, Machine->sample_rate, 0, pc_sh_update);
    return 0;
}



static void *pc_sh_custom_start(int clock, const struct CustomSound_interface *config)
{
	pc_sh_start();
	return (void *) ~0;
}



void pc_sh_speaker(int data)
{
	int mode = 0;
	pit8253_0_gate_w(2, data & 1);

	switch( data )
	{
		case 0: mode=0; break;
		case 1: case 2: mode=1; break;
		case 3: mode=2; break;
	}

	if( mode == speaker_gate )
		return;

    stream_update(channel);

    switch( mode )
	{
		case 0: /* completely off */
			SND_LOG(1,"PC_speaker",("off\n"));
			speaker_gate = 0;
            break;
		case 1: /* completely on */
			SND_LOG(1,"PC_speaker",("on\n"));
			speaker_gate = 1;
            break;
		case 2: /* play the tone */
			SND_LOG(1,"PC_speaker",("tone\n"));
			speaker_gate = 2;
            break;
    }
}

void pc_sh_speaker_change_clock(double pc_clock)
{
    stream_update(channel);
}



/*************************************
 *
 *	Sound handler update
 *
 *************************************/

void pc_sh_update(void *param, stream_sample_t **inputs, stream_sample_t **outputs, int length)
{
	static INT16 signal = 0x7fff;
	stream_sample_t *buffer = outputs[0];
	static int incr = 0;
	stream_sample_t *sample = buffer;
	int baseclock, rate = Machine->sample_rate / 2;

	baseclock = pit8253_get_frequency(0, 2);

	switch( speaker_gate ) {
	case 0:
		/* speaker off */
		while( length-- > 0 )
			*sample++ = 0;
		break;

	case 1:
		/* speaker on */
		while( length-- > 0 )
			*sample++ = 0x7fff;
		break;

	case 2:
		/* speaker gate tone from PIT channel #2 */
		if (baseclock > rate)
		{
			/* if the tone is too high to play, don't play it */
			while( length-- > 0 )
				*sample++ = 0;
		}
		else
		{
			while( length-- > 0 )
			{
				*sample++ = signal;
				incr -= baseclock;
				while( incr < 0 )
				{
					incr += rate;
					signal = -signal;
				}
			}
		}
		break;
	}
}

