/* << MSC V5.1 >> [FM-TOWNS] ************************************************
*
*	電子ﾎﾞﾘｭｰﾑ設定ﾌﾟﾛｸﾞﾗﾑ  (FMTOWNS専用)
*	------------------------------  FUNCTION  ----------------------------
*	----------------------------------------------------------------------
*	All Rights Reserved, Copyright (C) Y.Hirata 1989-1993.
*	Programmed by Y.Hirata ( NIFTY-ID: NAB03321  パオパオ )
*
*	NOTE: TAB=4
****************************************************************************/

#include <stdio.h>			/*  printf			*/
#include <stdlib.h>			/*  exit,atoi		*/
#include <string.h>			/*  strlen,strnicmp	*/
#include <conio.h>			/*  inp,outp		*/
#include "lib\typedef.h"
#include "lib\define.h"

#define	NONE		(-1)
#define	SUCCESS		0
#define	FAILURE		1
#define	NDEVICE		10
#define	NARGPARA	9
#define	MAXVOL		64
typedef	int		(*FUNCPT)( char * ) ;		/*  関数型定義			*/

int		AllMute = NONE ;

enum Values_for_EVOL {
		FM,		PCM,	LINE_L,	LINE_R,
		TV_L,	TV_R,	CD_L,	CD_R,
		MIC,	MODEM
} ;

struct	_PORT {
		int		evol ;
		int		mute ;
		int		val ;
		int		com ;
		int		data ;
} Port[NDEVICE] = {
		{	NONE,	0x00,	0x02,	0x04D5,	0x04D5	},
		{	NONE,	0x00,	0x01,	0x04D5,	0x04D5	},
		{	NONE,	0x00,	0x04,	0x04E1,	0x04E0	},
		{	NONE,	0x01,	0x05,	0x04E1,	0x04E0	},
		{	NONE,	0x02,	0x06,	0x04E1,	0x04E0	},
		{	NONE,	0x03,	0x07,	0x04E1,	0x04E0	},
		{	NONE,	0x00,	0x04,	0x04E3,	0x04E2	},
		{	NONE,	0x01,	0x05,	0x04E3,	0x04E2	},
		{	NONE,	0x02,	0x06,	0x04E3,	0x04E2	},
		{	NONE,	0x03,	0x07,	0x04E3,	0x04E2	}
} ;

/*	Prototype
--------------	*/
int chkMENU( char *str ) ;
int chkALL( char *str ) ;
int chkFM( char *str ) ;
int chkPCM( char *str ) ;
int chkLINE( char *str ) ;
int chkTV( char *str ) ;
int chkCD( char *str ) ;
int chkMIC( char *str ) ;
int chkMODEM( char *str ) ;

struct _ARG_CHK {
		int		len ;
		char	*str ;
		FUNCPT	func ;
} Args[] = {
		{	4,	"MENU",		chkMENU		},
		{	3,	"ALL",		chkALL		},
		{	2,	"FM",		chkFM		},
		{	3,	"PCM",		chkPCM		},
		{	4,	"LINE",		chkLINE		},
		{	2,	"TV",		chkTV		},
		{	2,	"CD",		chkCD		},
		{	3,	"MIC",		chkMIC		},
		{	5,	"MODEM",	chkMODEM	}
} ;

int chkMENU( char *str )
{
	return FAILURE ;
}

int chkALL( char *str )
{
	printf( "SET <ALL MUTE>\n" ) ;
	if ( strlen( str ) > 0 )
		AllMute = atoi( str ) ;
	else
		AllMute = 1 ;
	return SUCCESS ;
}

int chkFM( char *str )
{
	printf( "SET <FM>\n" ) ;
	if ( strlen( str ) > 0 )
		Port[FM].evol = atoi( str ) ;
	else
		Port[FM].evol = 0 ;
	return SUCCESS ;
}

int chkPCM( char *str )
{
	printf( "SET <PCM>\n" ) ;
	if ( strlen( str ) > 0 )
		Port[PCM].evol = atoi( str ) ;
	else
		Port[PCM].evol = 0 ;
	return SUCCESS ;
}

int chkLINE( char *str )
{
	printf( "SET <LINE IN>\n" ) ;
	if ( strlen( str ) > 0 ) {
		Port[LINE_L].evol = atoi( str ) ;
		Port[LINE_R].evol = atoi( str ) ;
	} else {
		Port[LINE_L].evol = MAXVOL ;
		Port[LINE_R].evol = MAXVOL ;
	}
	return SUCCESS ;
}

int chkTV( char *str )
{
	printf( "SET <TV>\n" ) ;
	if ( strlen( str ) > 0 ) {
		Port[TV_L].evol = atoi( str ) ;
		Port[TV_R].evol = atoi( str ) ;
	} else {
		Port[TV_L].evol = MAXVOL ;
		Port[TV_R].evol = MAXVOL ;
	}
	return SUCCESS ;
}

int chkCD( char *str )
{
	printf( "SET <CD>\n" ) ;
	if ( strlen( str ) > 0 ) {
		Port[CD_L].evol = atoi( str ) ;
		Port[CD_R].evol = atoi( str ) ;
	} else {
		Port[CD_L].evol = MAXVOL ;
		Port[CD_R].evol = MAXVOL ;
	}
	return SUCCESS ;
}

int chkMIC( char *str )
{
	printf( "SET <MIC>\n" ) ;
	if ( strlen( str ) > 0 )
		Port[MIC].evol = atoi( str ) ;
	else
		Port[MIC].evol = 0 ;
	return SUCCESS ;
}

int chkMODEM( char *str )
{
	printf( "SET <MODEM>\n" ) ;
	if ( strlen( str ) > 0 )
		Port[MODEM].evol = atoi( str ) ;
	else
		Port[MODEM].evol = MAXVOL ;
	return SUCCESS ;
}

void usage( void )
{
	printf( "\nUsage : EVOL [-option]\n" ) ;
	printf( "Option:\n" ) ;
/*	printf( "        -MENU      カーソルによる音量調整\n" ) ;*/
	printf( "        -ALL[n]    全体     n: 0=消音, 1=発音  標準: 1\n" ) ;
	printf( "        -FM[n]     FM音源   n: 0=消音, 1=発音  標準: 0\n" ) ;
	printf( "        -PCM[n]    PCM音源  n: 0=消音, 1=発音  標準: 0\n" ) ;
	printf( "        -LINE[n]   LINE  音量  n: 0〜64        標準: 64\n" ) ;
	printf( "        -TV[n]     TV    音量  n: 0〜64        標準: 64\n" ) ;
	printf( "        -CD[n]     CD    音量  n: 0〜64        標準: 64\n" ) ;
	printf( "        -MIC[n]    MIC   音量  n: 0〜64        標準: 0\n" ) ;
	printf( "        -MODEM[n]  MODEM 音量  n: 0〜64        標準: 64\n" ) ;
	printf( "Volume:\n" ) ;
	printf( "        0=-∞db, 1〜64=-32〜0db(64=MAX)\n" ) ;

	exit ( 1 ) ;
}

void evolSet( void )
{
	register int	cnt, mute ;
	int		all ;

	all = inp( 0x04EC ) ;
	outp( 0x04EC,0x1F ) ;			/*  ALL Mute On					*/

	mute = inp( Port[FM].com ) ;
	if ( Port[FM].evol != NONE ) {
		mute &= ~Port[FM].val ;
		mute |= ( Port[FM].evol ? Port[FM].val : Port[FM].mute ) ;
	}
	if ( Port[PCM].evol != NONE ) {
		mute &= ~Port[PCM].val ;
		mute |= ( Port[PCM].evol ? Port[PCM].val : Port[PCM].mute ) ;
	}
	outp( Port[FM].com,mute ) ;		/*  FM & PCM					*/

	for ( cnt=2; cnt<NDEVICE; cnt++ ) {
		if ( Port[cnt].evol != NONE ) {
			if ( Port[cnt].evol ) {			/*  可変		*/
				outp( Port[cnt].com,Port[cnt].val ) ;
				outp( Port[cnt].data,Port[cnt].evol-1 ) ;
			} else {						/*  ﾐｭｰﾄ		*/
				outp( Port[cnt].com,Port[cnt].mute ) ;
				outp( Port[cnt].data,0 ) ;
			}
		}
	}

	if ( AllMute != NONE ) {
		if ( AllMute )
			outp( 0x04EC,0x5F ) ;	/*  ALL Mute Off				*/
		else
			outp( 0x04EC,0x1F ) ;	/*  ALL Mute On					*/
	} else {
		if ( all & 0x40 )
			outp( 0x04EC,0x5F ) ;	/*  ALL Mute Off				*/
		else
			outp( 0x04EC,0x1F ) ;	/*  ALL Mute On					*/
	}
}

void main( int ac,char *av[] )
{
	register int	cnt, cnt2 ;
	int		flg ;

	printf( "Set Electronic Volume  V1.00  (C) パオパオ 1993.\n" ) ;
	if ( ac < 2 ) usage() ;
	for ( cnt=1; cnt<ac; cnt++ ) {
		if ( *av[cnt] == '-' || *av[cnt] == '/' ) {
			if ( *(av[cnt]+1) == '?' ) usage() ;
			flg = FAILURE ;
			for ( cnt2=0; cnt2<NARGPARA; cnt2++ ) {
				if ( !strnicmp( av[cnt]+1,Args[cnt2].str,Args[cnt2].len ) ) {
					flg = Args[cnt2].func( av[cnt]+1+Args[cnt2].len ) ;
				}
			}
			if ( flg == FAILURE ) usage() ;
		} else {
			usage() ;
		}
	}
	evolSet() ;

	exit( 0 ) ;
}

