/***************************************************************************
*	NAME:  MIXER.C
**	COPYRIGHT:
**	"Copyright (c) 1993, by FORTE
**
**       "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."
****************************************************************************
*  CREATION DATE: 10/04/93
*--------------------------------------------------------------------------*
*     VERSION	DATE	   NAME		DESCRIPTION
*>	1.0	10/04/93		Original
***************************************************************************/
#include <stdio.h>
#include <dos.h>
#include <conio.h>

#include "forte.h"
#include "ultraerr.h"
#include "mixer.h"
#include "gf1hware.h"
#include "gf1os.h"

extern ULTRA_DATA _gf1_data;
ULTRA_MIXER _mixer_data;

int
UltraMixProbe(unsigned int base_port)
{
unsigned char val;

val = inp(base_port+MIX_SEL_PORT);

/* There may have to be some additional checks here if later versions */
/* of the card (post 3.6) might NOT have the ICS mixer. For now, anything */
/* later than 5 will have a mixer */

/* NOTE: Version 8-11 (0x08-x0B) is UltraMax. No ICS mixer on MAX */

if ((val >= 5 && val <=7) || (val >= 0x81 && val <= 0x90))
	{
	_mixer_data.mixer_addr = base_port+MIX_SEL_PORT;
	_mixer_data.mixer_data = base_port+MIX_DATA_PORT;
	UltraMixMute(MIX_MIKE_IN,FALSE);
	UltraMixMute(MIX_LINE_IN,FALSE);
	UltraMixMute(MIX_CD_IN,FALSE);
	UltraMixMute(MIX_GF1_OUT,FALSE);
	UltraMixMute(MIX_CHAN_4,FALSE);
	UltraMixMute(MIX_MASTER,FALSE);
	return((int)val);
	}

return(0);
}

#define FLIP_REV	5	/* Flip some mixer channels if this revision */

static unsigned char flip_left[6] = {
	0x01,		/* MIC IN */
	0x01,		/* LINE IN */
	0x01,		/* CD IN */
	0x02,		/* GF1_OUT */
	0x01,		/* UNUSED */
	0x02 };		/* MASTER OUT */

static unsigned char flip_right[6] = {
	0x02,		/* MIC IN */
	0x02,		/* LINE IN */
	0x02,		/* CD IN */
	0x01,		/* GF1_OUT */
	0x02,		/* UNUSED */
	0x01 };		/* MASTER OUT */

void
UltraMixAttn(int chan, int left, int value, int revision)
{
unsigned char ctrl_addr;
unsigned char attn_addr;
unsigned char normal;

ctrl_addr = chan << 3;		/* Shift up to the channel address bits */
attn_addr = chan << 3;		/* Shift up to the channel address bits */

if (left == MIX_LEFT)
	{
	ctrl_addr |= MIX_CTRL_LEFT;
	attn_addr |= MIX_ATTN_LEFT;
	if (_mixer_data.mute[chan] == TRUE)
		normal = 0;
	else
		if (revision == FLIP_REV)
			normal = flip_left[chan];
		else
			normal = 0x01;
	}
else
	{
	ctrl_addr |= MIX_CTRL_RIGHT;
	attn_addr |= MIX_ATTN_RIGHT;
	if (_mixer_data.mute[chan] == TRUE)
		normal = 0;
	else
		if (revision == FLIP_REV)
			normal = flip_right[chan];
		else
			normal = 0x02;
	}

ENTER_CRITICAL;

outp(_mixer_data.mixer_addr,ctrl_addr);	/* select the proper RL chan ... */
outp(_mixer_data.mixer_data,normal);	/* set to normal mode */

outp(_mixer_data.mixer_addr,attn_addr);	/* select the proper RL chan ... */
outp(_mixer_data.mixer_data,value);	/* set the value */

LEAVE_CRITICAL;
}

void
UltraMixXparent(int revision)
{
	UltraMixAttn(MIX_MIKE_IN, MIX_LEFT, 0x7f, revision);
	UltraMixAttn(MIX_MIKE_IN, MIX_RIGHT, 0x7f, revision);
	UltraMixAttn(MIX_LINE_IN, MIX_LEFT, 0x7f, revision);
	UltraMixAttn(MIX_LINE_IN, MIX_RIGHT, 0x7f, revision);
	UltraMixAttn(MIX_CD_IN, MIX_LEFT, 0x7f, revision);
	UltraMixAttn(MIX_CD_IN, MIX_RIGHT, 0x7f, revision);
	UltraMixAttn(MIX_GF1_OUT, MIX_LEFT, 0x7f, revision);
	UltraMixAttn(MIX_GF1_OUT, MIX_RIGHT, 0x7f, revision);
	UltraMixAttn(MIX_CHAN_4, MIX_LEFT, 0x00, revision);		/* Unused ... */
	UltraMixAttn(MIX_CHAN_4, MIX_RIGHT, 0x00, revision);	/* Unused ... */
	UltraMixAttn(MIX_MASTER, MIX_LEFT, 0x7f, revision);
	UltraMixAttn(MIX_MASTER, MIX_RIGHT, 0x7f, revision);
	// On these rev boards, there is no enable/disable for mic or line in.
	// so use the ICS mixer to mute inputs. NOTE: They are UN-MUTED here so
	// that apps that are not aware of the ICS mixer will will work ...
	if (revision >= 0x81 && revision <= 0x91)
		{
		UltraMixMute(MIX_LINE_IN,FALSE);
		UltraMixMute(MIX_MIKE_IN,FALSE);
		}
}

void
UltraMixMute(int chan,int flag)
{
_mixer_data.mute[chan] = flag;
}

