/***************************************************************************
*       NAME:  DAC.C $Revision: 1.18 $
**      COPYRIGHT:
**      "Copyright (c) 1994,1995 by e-Tek Labs"
**
**       "This software is furnished under a license and may be used,
**       copied, or disclosed only in accordance with the terms of such
**       license and with the inclusion of the above copyright notice.
**       This software or any other copies thereof may not be provided or
**       otherwise made available to any other person. No title to and
**       ownership of the software is hereby transfered."
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>

#include "sbosdefs.h"
#include "sbosdata.h"
#include "shared.h"
#include "dac.h"

void synth_handler(void);
void asm_codec_freq(void);

extern SHARED shared;
extern unsigned int dsp_dma_rate;
extern unsigned int dsp_old_dma_rate;
extern unsigned int reg_codec_addr;
extern unsigned int reg_codec_data;
extern unsigned int reg_codec_status;
extern unsigned int reg_codec_pio;

extern unsigned int reg_mixer;
extern unsigned int reg_2xBindexed;
extern unsigned int reg_2xFcontrol;
extern unsigned char regctl_mask;
extern unsigned int reg_update_sb2xa;
extern unsigned char spec_eoi;
extern unsigned char pic_mask;
extern unsigned char mixer_mask;
extern unsigned int orig_irq1;

#ifndef VAR_PCM
CODEC_FREQ codec_freq[14] = {
	{5510U, 0x00|XTAL2,0},
	{6620U, 0x0E|XTAL2,0},
	{8000U, 0x00|XTAL1,0},
	{9600U, 0x0E|XTAL1,0},
	{11025U,0x02|XTAL2,0},
	{16000U,0x02|XTAL1,0},
	{18900U,0x04|XTAL2,0},
	{22050U,0x06|XTAL2,0},
	{27420U,0x04|XTAL1,0},
	{32000U,0x06|XTAL1,0},
	{33075U,0x0C|XTAL2,0},
	{37800U,0x08|XTAL2,0},
	{44100U,0x0A|XTAL2,0},
	{48000U,0x0C|XTAL1,0}
};
#endif

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

FUNCTION DEFINITION:
SetPic -

DESCRIPTION:

EXPECTS:

MODIFIES:

SEE ALSO:

RETURNS:

*/
void SetPic(void)
{
unsigned char val;
unsigned int imr;

	if(orig_irq1 > 7)
		imr = 0xa1;
	else
		imr = 0x21;

	/* unmask synth interrupt */
	val = inp(imr);
	val &= pic_mask;
	outp(imr,val);
	outp(imr-1,spec_eoi);

	/* Un-mask IRQ 2 from first controller if using 2nd controller */
	if (orig_irq1 > 7)
		{
		val = inp(0x21);
		val &= 0xFB;
// TEST CODE FOR INCA ..... (make sure you REMOVE the if (0))
//		if (0)
			outp(0x21,val);
		outp(0x20,0x62);
		}
#ifdef NEVER
	if (!(shared.status & STAT_COMBINED_IRQ))
		synth_handler();	// Deal with and pending IRQs
#endif
}

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

FUNCTION DEFINITION:
wait_mce_format -

DESCRIPTION:

EXPECTS:

MODIFIES:

SEE ALSO:

RETURNS:

*/
void pascal wait_mce_format(unsigned char data,unsigned char format)
{

outp(reg_codec_addr,CODEC_MCE|format);
outp(reg_codec_data,data);
(void)inp(reg_codec_data);		/* ERRATA SHEETS ... */
(void)inp(reg_codec_data);		/* ERRATA SHEETS ... */

/* wait till sync is done ... */
while (inp(reg_codec_addr) & (UCHAR)0x80)
	;

/* Need this. outp doesn't always take ... .*/
while(TRUE)
	{
	/* turn off the MCE bit */
	outp(reg_codec_addr,format);
	if(inp(reg_codec_addr) == format)
		break;
	}

}

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

FUNCTION DEFINITION:
set_dma_rate -

DESCRIPTION:

EXPECTS:

MODIFIES:

SEE ALSO:

RETURNS:

*/
void set_dma_rate(void)
{
unsigned int thertz;
int i;
unsigned char format;
unsigned int diff1,diff2;

if (dsp_dma_rate != dsp_old_dma_rate)
	{
#ifdef VAR_PCM
	// We can do better here with IW than MAX
	// since we have 255 frequencies. MAX has 14.
	if (dsp_dma_rate < 3500)
		dsp_dma_rate = 3500;
	if (dsp_dma_rate > 22050)
		dsp_dma_rate = 22050;
	
	 _CX = dsp_dma_rate;
	 asm_codec_freq();
#else

	thertz = dsp_dma_rate;

	if (thertz > 48000U)
		thertz = 48000U;

	for (i=0;i<14;i++)
		{
		if (thertz <= codec_freq[i].hertz)
			{
			if (i == 0)
				break;
			diff1 = thertz - codec_freq[i-1].hertz;
			diff2 = codec_freq[i].hertz - thertz;
			if (diff1 < diff2)
				i--;
			break;
			}
		}

	format = codec_freq[i].bits;
	wait_mce_format(format,PLAYBK_FORMAT);
	wait_mce_format(format&0xf0,REC_FORMAT);
#endif
	}
	dsp_old_dma_rate = dsp_dma_rate;

return;
}

