/*************************************************************************
*	TG300 MULTI PART
*************************************************************************/

int		Tg300partAdrOfs[16] = 
{
	0x100,0x200,0x300,0x400,0x500,0x600,0x700,0x800,0x900,0x000,0xA00,0xB00,0xC00,0xD00,0xE00,0xF00
};

int		tg300_getPart( char *s )
{
	int		part;

	part = atoi(s) - 1;
	if ( part < 0 || part > 15 )
		return (-1);
	return (part);
}

/*************************************************************************
*	ELEMENT RESERVE
*-------------------------------------------------------------------------
*	exTG300_elementReserve(part,n)
*		part	…	1 〜 16
*************************************************************************/

int		exTG300_elementReserve( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[4];
	int		part, v;

	if ( argc != 2 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"ELEMENT RESERVE\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	v = atoi(argv[1]);
	if ( v < 0 || v > 32 )
		goto _ERR;
	dat[0] = v;
	return tg300_genMML( sqr, bufSiz, buf, 0x020000+Tg300partAdrOfs[part], 1, dat );
}


/*************************************************************************
*	BANK SELECT
*-------------------------------------------------------------------------
*	exTG300_bank(part,msb,lsb)
*		part	…	1 〜 16
*************************************************************************/

int		exTG300_bank( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[4];
	int		part, msb, lsb;

	if ( argc != 3 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"BANK SELECT\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	msb = atoi(argv[1]);	if ( msb < 0 || msb > 0x7F )	goto _ERR;
	lsb = atoi(argv[2]);	if ( lsb < 0 || lsb > 0x7F )	goto _ERR;
	dat[0] = msb;
	dat[1] = lsb;
	return tg300_genMML( sqr, bufSiz, buf, 0x020001+Tg300partAdrOfs[part], 2, dat );
}


/*************************************************************************
*	PROGRAM NUMBER
*-------------------------------------------------------------------------
*	exTG300_programNo(part,prog)
*		part	…	1 〜 16
*		prog	…	1〜128
*************************************************************************/

int		exTG300_programNo( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[4];
	int		part, v;

	if ( argc != 2 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"PROGRAM NUMBER\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	v = atoi(argv[1]) - 1;
	if ( v < 0 || v > 127 )
		goto _ERR;
	dat[0] = v;
	return tg300_genMML( sqr, bufSiz, buf, 0x020003+Tg300partAdrOfs[part], 2, dat );
}

/*************************************************************************
*	Rcv CHANNEL
*-------------------------------------------------------------------------
*	exTG300_rcvChannel(part,ch)
*	part	…	1 〜 16
*	ch		…	0〜16
*************************************************************************/

int		exTG300_rcvChannel( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[4];
	int		part, v;

	if ( argc != 2 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"Rcv CHANNEL\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	v = atoi(argv[1]);
	if ( v == 0 )
		v = 0x10;	/* OFF */
	else
		--v;
	if ( v < 0 || v > 16 )
		goto _ERR;
	dat[0] = v;
	return tg300_genMML( sqr, bufSiz, buf, 0x020004+Tg300partAdrOfs[part], 1, dat );
}

/*************************************************************************
*	MONO/POLY MODE
*-------------------------------------------------------------------------
*	exTG300_monoPolyMode(part,mode)
*	part	…	1 〜 16
*	mode	…	0:MONO
*				1:POLY
*************************************************************************/

int		exTG300_monoPolyMode( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[4];
	int		part, v;

	if ( argc != 2 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"MONO/POLY MODE\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	v = atoi(argv[1]);
	if ( v < 0 || v > 1 )
		goto _ERR;
	dat[0] = v;
	return tg300_genMML( sqr, bufSiz, buf, 0x020015+Tg300partAdrOfs[part], 1, dat );
}

/*************************************************************************
*	SAME NOTE NUMBER KEY ON ASSIGN
*-------------------------------------------------------------------------
*	exTG300_keyAssign(part,mode)
*	part	…	1 〜 16
*	mode	…	0:SINGLE
*				1:MULTI
*				2:INST
*************************************************************************/

int		exTG300_keyAssign( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[4];
	int		part, v;

	if ( argc != 2 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"SAME NOTE NUMBER KEY ON ASSIGN\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	v = atoi(argv[1]);
	if ( v < 0 || v > 2 )
		goto _ERR;
	dat[0] = v;
	return tg300_genMML( sqr, bufSiz, buf, 0x020016+Tg300partAdrOfs[part], 1, dat );
}

/*************************************************************************
*	PART MODE
*-------------------------------------------------------------------------
*	exTG300_partMode(part,mode)
*		part	…	1 〜 16
*		mode	…	0:NORMAL
*					1:DRUM
*************************************************************************/

int		exTG300_partMode( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[4];
	int		part, v;

	if ( argc != 2 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"PART MODE\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	v = atoi(argv[1]);
	if ( v < 0 || v > 1 )
		goto _ERR;
	dat[0] = v;
	return tg300_genMML( sqr, bufSiz, buf, 0x020017+Tg300partAdrOfs[part], 1, dat );
}

/*************************************************************************
*	NOTE SHIFT
*-------------------------------------------------------------------------
*	exTG300_noteShift(part,shift)
*		part	…	1 〜 16
*		shift	…	-24〜+24
*************************************************************************/

int		exTG300_noteShift( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[4];
	int		part, v;

	if ( argc != 2 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"NOTE SHIFT\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	v = atoi(argv[1]) + 0x40;
	if ( v < 0x28 || v > 0x58 )
		goto _ERR;
	dat[0] = v;
	return tg300_genMML( sqr, bufSiz, buf, 0x020018+Tg300partAdrOfs[part], 1, dat );
}

/*************************************************************************
*	DETUNE
*-------------------------------------------------------------------------
*	exTG300_detune(part,shift)
*	part	…	1 〜 16
*	shift	…	-128〜+127
*************************************************************************/

int		exTG300_detune( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[4];
	int		part, v;

	if ( argc != 2 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"DETUNE\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	v = atoi(argv[1]) + 0x80;
	if ( v < 0x00 || v > 0xFF )
		goto _ERR;
	dat[0] = (v >> 4) & 0x0F;
	dat[1] =  v       & 0x0F;
	return tg300_genMML( sqr, bufSiz, buf, 0x020019+Tg300partAdrOfs[part], 2, dat );
}

/*************************************************************************
*	VOLUME
*-------------------------------------------------------------------------
*	exTG300_volume(part,vol)
*		part	…	1 〜 16
*		vol		…	0 〜127
*************************************************************************/

int		exTG300_volume( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[4];
	int		part, v;

	if ( argc != 2 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"VOLUME\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	v = atoi(argv[1]);
	if ( v < 0 || v > 0x7F )
		goto _ERR;
	dat[0] = v;
	return tg300_genMML( sqr, bufSiz, buf, 0x02001B+Tg300partAdrOfs[part], 1, dat );
}


/*************************************************************************
*	VELOCITY SENSE DEPTH
*-------------------------------------------------------------------------
*	exTG300_velSensDepth(part,depth)
*		part	…	1 〜 16
*		depth	…	0 〜127
*************************************************************************/

int		exTG300_velSensDepth( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[4];
	int		part, v;

	if ( argc != 2 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"VELOCITY SENSE DEPTH\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	v = atoi(argv[1]);
	if ( v < 0 || v > 0x7F )
		goto _ERR;
	dat[0] = v;
	return tg300_genMML( sqr, bufSiz, buf, 0x02001C+Tg300partAdrOfs[part], 1, dat );
}

/*************************************************************************
*	VELOCITY SENSE OFFSET
*-------------------------------------------------------------------------
*	exTG300_velSensOffst(part,offset)
*		part	…	1 〜 16
*		offset	…	0 〜127
*************************************************************************/

int		exTG300_velSensOffst( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[4];
	int		part, v;

	if ( argc != 2 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"VELOCITY SENSE OFFSET\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	v = atoi(argv[1]);
	if ( v < 0 || v > 0x7F )
		goto _ERR;
	dat[0] = v;
	return tg300_genMML( sqr, bufSiz, buf, 0x02001D+Tg300partAdrOfs[part], 1, dat );
}

/*************************************************************************
*	PAN
*-------------------------------------------------------------------------
*	exTG300_pan(part,pan)
*		part	…	1 〜 16
*		pan		…	rnd, -63〜0〜63
*************************************************************************/

int		exTG300_pan( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[4];
	int		part, v;

	if ( argc != 2 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"PAN\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	if ( strcmpi(argv[1],"rnd") == 0 )
		v = 0;
	else
	{
		v = atoi(argv[1]);
		if ( v < -63 || v > 63 )
			goto _ERR;
		v += 64;
	}
	dat[0] = v;
	return tg300_genMML( sqr, bufSiz, buf, 0x02001E+Tg300partAdrOfs[part], 1, dat );
}


/*************************************************************************
*	MW CONTROL
*-------------------------------------------------------------------------
*	exTG300_mwControl(part,pitch,filter,amp,pmod,fmod)
*		part	…	1 〜 16
*		pitch	…	-24〜24
*		filter	…	-64〜63
*		amp		…	-64〜63
*		pmod	…	0〜127
*		fmod	…	0〜127
*************************************************************************/

int		exTG300_mwControl( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[8];
	int		part, pitch, filter, amp, pmod, fmod;

	if ( argc != 6 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"MW CONTROL\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	pitch  = atoi(argv[1]) + 0x40;
	filter = atoi(argv[2]) + 0x40;
	amp    = atoi(argv[3]) + 0x40;
	pmod   = atoi(argv[4]);
	fmod   = atoi(argv[5]);
	if ( pitch < 0x28 || pitch > 0x58 || filter < 0 || filter > 0x7F
	|| amp < 0 || amp > 0x7F || pmod < 0 || pmod > 0x7F || fmod <  0 || fmod > 0x7F )
		goto _ERR;
	dat[0] = pitch;
	dat[1] = filter;
	dat[2] = amp;
	dat[3] = pmod;
	dat[4] = fmod;
	return tg300_genMML( sqr, bufSiz, buf, 0x02003B+Tg300partAdrOfs[part], 5, dat );
}


/*************************************************************************
*	BEND CONTROL
*-------------------------------------------------------------------------
*	exTG300_bendControl(part,pitch,filter,amp,pmod,fmod)
*		part	…	1 〜 16
*		pitch	…	-24〜24
*		filter	…	-64〜63
*		amp		…	-64〜63
*		pmod	…	0〜127
*		fmod	…	0〜127
*************************************************************************/

int		exTG300_bendControl( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[8];
	int		part, pitch, filter, amp, pmod, fmod;

	if ( argc != 6 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"BEND CONTROL\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	pitch  = atoi(argv[1]) + 0x40;
	filter = atoi(argv[2]) + 0x40;
	amp    = atoi(argv[3]) + 0x40;
	pmod   = atoi(argv[4]);
	fmod   = atoi(argv[5]);
	if ( pitch < 0x28 || pitch > 0x58 || filter < 0 || filter > 0x7F
	|| amp < 0 || amp > 0x7F || pmod < 0 || pmod > 0x7F || fmod <  0 || fmod > 0x7F )
		goto _ERR;
	dat[0] = pitch;
	dat[1] = filter;
	dat[2] = amp;
	dat[3] = pmod;
	dat[4] = fmod;
	return tg300_genMML( sqr, bufSiz, buf, 0x020041+Tg300partAdrOfs[part], 5, dat );
}

/*************************************************************************
*	CAT CONTROL
*-------------------------------------------------------------------------
*	exTG300_catControl(part,pitch,filter,amp,pmod,fmod)
*		part	…	1 〜 16
*		pitch	…	-24〜24
*		filter	…	-64〜63
*		amp		…	-64〜63
*		pmod	…	0〜127
*		fmod	…	0〜127
*************************************************************************/

int		exTG300_catControl( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[8];
	int		part, pitch, filter, amp, pmod, fmod;

	if ( argc != 6 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"CAT CONTROL\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	pitch  = atoi(argv[1]) + 0x40;
	filter = atoi(argv[2]) + 0x40;
	amp    = atoi(argv[3]) + 0x40;
	pmod   = atoi(argv[4]);
	fmod   = atoi(argv[5]);
	if ( pitch < 0x28 || pitch > 0x58 || filter < 0 || filter > 0x7F
	|| amp < 0 || amp > 0x7F || pmod < 0 || pmod > 0x7F || fmod <  0 || fmod > 0x7F )
		goto _ERR;
	dat[0] = pitch;
	dat[1] = filter;
	dat[2] = amp;
	dat[3] = pmod;
	dat[4] = fmod;
	return tg300_genMML( sqr, bufSiz, buf, 0x020047+Tg300partAdrOfs[part], 5, dat );
}

/*************************************************************************
*	PAT CONTROL
*-------------------------------------------------------------------------
*	exTG300_patControl(part,pitch,filter,amp,pmod,fmod)
*		part	…	1 〜 16
*		pitch	…	-24〜24
*		filter	…	-64〜63
*		amp		…	-64〜63
*		pmod	…	0〜127
*		fmod	…	0〜127
*************************************************************************/

int		exTG300_patControl( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[8];
	int		part, pitch, filter, amp, pmod, fmod;

	if ( argc != 6 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"PAT CONTROL\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	pitch  = atoi(argv[1]) + 0x40;
	filter = atoi(argv[2]) + 0x40;
	amp    = atoi(argv[3]) + 0x40;
	pmod   = atoi(argv[4]);
	fmod   = atoi(argv[5]);
	if ( pitch < 0x28 || pitch > 0x58 || filter < 0 || filter > 0x7F
	|| amp < 0 || amp > 0x7F || pmod < 0 || pmod > 0x7F || fmod <  0 || fmod > 0x7F )
		goto _ERR;
	dat[0] = pitch;
	dat[1] = filter;
	dat[2] = amp;
	dat[3] = pmod;
	dat[4] = fmod;
	return tg300_genMML( sqr, bufSiz, buf, 0x02004D+Tg300partAdrOfs[part], 5, dat );
}

/*************************************************************************
*	AC1 CONTROL
*-------------------------------------------------------------------------
*	exTG300_ac1Control(part,pitch,filter,amp,pmod,fmod)
*		part	…	1 〜 16
*		pitch	…	-24〜24
*		filter	…	-64〜63
*		amp		…	-64〜63
*		pmod	…	0〜127
*		fmod	…	0〜127
*************************************************************************/

int		exTG300_ac1Control( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[8];
	int		part, pitch, filter, amp, pmod, fmod;

	if ( argc != 6 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"AC1 CONTROL\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	pitch  = atoi(argv[1]) + 0x40;
	filter = atoi(argv[2]) + 0x40;
	amp    = atoi(argv[3]) + 0x40;
	pmod   = atoi(argv[4]);
	fmod   = atoi(argv[5]);
	if ( pitch < 0x28 || pitch > 0x58 || filter < 0 || filter > 0x7F
	|| amp < 0 || amp > 0x7F || pmod < 0 || pmod > 0x7F || fmod <  0 || fmod > 0x7F )
		goto _ERR;
	dat[0] = pitch;
	dat[1] = filter;
	dat[2] = amp;
	dat[3] = pmod;
	dat[4] = fmod;
	return tg300_genMML( sqr, bufSiz, buf, 0x020053+Tg300partAdrOfs[part], 5, dat );
}

/*************************************************************************
*	AC2 CONTROL
*-------------------------------------------------------------------------
*	exTG300_ac2Control(part,pitch,filter,amp,pmod,fmod)
*		part	…	1 〜 16
*		pitch	…	-24〜24
*		filter	…	-64〜63
*		amp		…	-64〜63
*		pmod	…	0〜127
*		fmod	…	0〜127
*************************************************************************/

int		exTG300_ac2Control( char *sqr, size_t bufSiz, char *buf, int argc, char **argv )
{
	char	dat[8];
	int		part, pitch, filter, amp, pmod, fmod;

	if ( argc != 6 )
	{
_ERR:	MM_setErrMsg(sqr,"TG300 \"AC2 CONTROL\" error!");
		return(ERR);
	}
	if ( (part = tg300_getPart(argv[0])) < 0 )
		goto _ERR;
	pitch  = atoi(argv[1]) + 0x40;
	filter = atoi(argv[2]) + 0x40;
	amp    = atoi(argv[3]) + 0x40;
	pmod   = atoi(argv[4]);
	fmod   = atoi(argv[5]);
	if ( pitch < 0x28 || pitch > 0x58 || filter < 0 || filter > 0x7F
	|| amp < 0 || amp > 0x7F || pmod < 0 || pmod > 0x7F || fmod <  0 || fmod > 0x7F )
		goto _ERR;
	dat[0] = pitch;
	dat[1] = filter;
	dat[2] = amp;
	dat[3] = pmod;
	dat[4] = fmod;
	return tg300_genMML( sqr, bufSiz, buf, 0x020059+Tg300partAdrOfs[part], 5, dat );
}

