/*
**	tx1p64 -- Merge a 1-performance dump into a 64-performance dump
**	tx64p1 -- Extract a 1-performance dump from a 64-performance dump
**	Return 0 for failure, 1 for success.
**	psl, 3/88
** Note, the location of KMOD (from byte 32 of the 64-p dump) in the 1-perf
** dump is undocumented; I made a guess (TX1PKMODLOC) in libdx7.h, but if
** we ever find out the true location, that should be updated...
*/

#include <stdio.h>
#include <midi.h>
#include <dx7voice.h>

#define	OOOOOX	0x01	/* 1 bit mask */
#define	OOOOXX	0x03	/* 2 bit mask */
#define	OOOXXX	0x07	/* 3 bit mask */
#define	OOXXXX	0x0F	/* 4 bit mask */
#define	OOXOOO	0x08	/* weird 1 bit mask */

tx1p64(p1, n, p64)	/* merge p1 into p64 in slot n */
u_char	*p1, *p64;	/* These point to the data AFTER the header */
{
	register u_char *f, *t;
	register int v;

	if (n < 0 || n >= 32			/* out of range */
	 || *p1 == SX_CMD)			/* common error */
	    return(0);
	for (v = 0; v < 2; v++) {
	    f = &p1[v * TX1PVLEN];
	    t = &p64[n * TX64PLEN + v * TX64PVLEN];
	    t[0] = (f[2] << 6);			/* P/M */
	    t[1] = ((f[4] & OOOXXX) << 4) + f[3];/* PBS(LO) | PBR */
	    t[2] = f[5];			/* PTIM */
	    t[3] = (f[7] << 2) + f[6];		/* M | GL */
	    t[4] = (f[10] << 4) + f[9];		/* MWA | MWS */
	    t[5] = (f[12] << 4) + f[11];	/* FCA | FCS */
	    t[6] = (f[14] << 4) + f[13];	/* ATA | ATS */
	    t[7] = (f[16] << 4) + f[15];	/* BCA | BCS */
	    bzero(&t[8], 6);
	    t[14] = f[26];			/* ATN */
	    t[15] = ((f[4] & OOXOOO) << 3);	/* PBS(HI) [!] */
	}
	f = p1;
	t = &p64[n * TX64PLEN];
	t[32] = (f[61] << 2) + f[60];		/* VMS | KMOD (see comment) */
	t[33] = 0;
	bcopy(&f[64], &t[34], 30);
	return(1);
}

tx64p1(p64, n, p1)	/* extract slot n of p64 into p1 */
u_char	*p64, *p1;	/* These point to the data AFTER the header */
{
	register u_char *f, *t;
	register int v;

	if (n < 0 || n >= 32			/* out of range */
	 || *p64 == SX_CMD)			/* common error */
	    return(0);
	for (v = 0; v < 2; v++) {
	    f = &p64[n * TX64PLEN + v * TX64PVLEN];
	    t = &p1[v * TX1PVLEN];
	    t[0] = t[1] = 0;
	    t[2] = (f[0] >> 6);			/* P/M */
	    t[3] = (f[1] & OOXXXX);		/* PBR */
	    t[4] = (f[15] >> 3) + (f[1] >> 4);	/* PBS [!] */
	    t[5] = f[2];			/* PTIM */
	    t[6] = (f[3] & OOOOOX);			/* GL */
	    t[7] = (f[3] >> 1);			/* M */
	    t[8] = 0;
	    t[9] = (f[4] & OOXXXX);		/* MWS */
	    t[10] = (f[4] >> 4);		/* MWA */
	    t[11] = (f[5] & OOXXXX);		/* FCS */
	    t[12] = (f[5] >> 4);		/* FCA */
	    t[13] = (f[6] & OOXXXX);		/* ATS */
	    t[14] = (f[6] >> 4);		/* ATA */
	    t[15] = (f[7] & OOXXXX);		/* BCS */
	    t[16] = (f[7] >> 4);		/* BCA */
	    bzero(&t[17], 13);
	    t[26] = f[14];			/* ATN */
	}
	f = &p64[n * TX64PLEN];
	t = p1;
	t[60] = (f[32] & OOOOXX);		/* KMOD (see comment) */
	t[61] = (f[32] >> 2);			/* VMS */
	t[62] = t[63] = 0;
	bcopy(&f[34], &t[64], 30);		/* PNAM */
	return(1);
}
