/*
**	TXELD -- Load voice(s) and/or performance(s) into TX816 edit buffer(s)
*/

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

#d HLEN		6		/* length of sysex header */
#d MAX1LEN	(TX1PLEN + DX7VOXLEN)	/* need room for either */

main(argc, argv)
char *argv[];
{
	int i;

	av0 = argv[0];
	for (i = 1; i < argc; i++) {
	    if (argv[i][0] == '-') {
		switch (argv[i][1]) {
		case 'p':		/* load performance */
		    put(argv[i], TX_SXF_1P, TX1PLEN);
		    break;
		case 'v':		/* load voice */
		    put(argv[i], DX7_SXF_1V, DX7VOXLEN);
		    break;
		default:
		    use();
		}
	    }
	}
	exit(0);
}

put(arg, sxfmt, sxlen)
char	*arg;
{
	register char *cp;
	u_char sxbuf[HLEN + MAX1LEN];
	char buf[4];
	int mfh, fh, chan;

	for (cp = arg; *cp && *cp != '='; cp++);
	if (*cp != '=') {
	    fprintf(stderr, "%s: missing '=' in %s\n", av0, arg);
	    use();
	}
	*cp++ = '\0';
	if (*cp == '-' && cp[1] == '\0')
	    fh = 0;
	else if ((fh = open(cp, 0)) < 0) {
	    perror(cp);
	    use();
	}
	chan = atoi(&arg[2]) - 1;
	if (chan < 0 || 15 < chan) {
	    fprintf(stderr, "%s: bad chan number (%d)\n", av0, chan);
	    use();
	}
	if (pvfile(fh, sxfmt, sxlen, sxbuf) == 0)
	    return;
	sxbuf[2] = chan;
#ifdef	TEST
	if ((mfh = creat("txput.test", 0644)) == -1) {
	    fprintf(stderr, "%s: ", av0);
	    perror("txput.test");
	    exit(1);
	}
#else
	if ((mfh = open(MidiDevice, 2)) == -1) {
	    fprintf(stderr, "%s: ", av0);
	    perror(MidiDevice);
	    exit(1);
	}
	MpuSetTrack(mfh, MPU_TR_COM);
	buf[0] = MPU_RESET;
	buf[1] = MPU_MIDI_THRU_OFF;
	buf[2] = MPU_SEND_SYSTEM_MESSAGE;
	write(mfh, buf, 3);
#endif
	write(mfh, sxbuf, HLEN + sxlen);
	buf[0] = CheckSum(&sxbuf[HLEN], sxlen);
	buf[1] = SX_EOB;
	write(mfh, buf, 2);
#ifndef	TEST
	MpuSetTrack(mfh, 0);
#endif
	close(mfh);
}

pvfile(fh, fmt, len, cp)
u_char	*cp;
{
	u_char buf[2];
	int lhi, llo;

	lhi = len / 128;
	llo = len % 128;
	while (read(fh, cp, 1) == 1 && *cp != SX_CMD);
	if (read(fh, &cp[1], 5) != 5) {
	    fprintf(stderr, "%s: EOF in file header?\n", av0);
	    return(0);
	}
	if (cp[1] != ID_YAMAHA
	 || cp[3] != fmt
	 || cp[4] != lhi || cp[5] != llo) {
	    fprintf(stderr, "%s: naughty file header:", av0);
	    fprintf(stderr, " %x %x %x %x %x\n",
	     cp[1], cp[2], cp[3], cp[4], cp[5]);
	    return(0);
	}
	if (read(fh, &cp[6], len) != len) {
	    fprintf(stderr, "%s: EOF in file body?\n", av0);
	    return(0);
	}
	if (read(fh, buf, 2) != 2) {
	    fprintf(stderr, "%s: EOF in checksum/SX_EOB?\n", av0);
	    return(0);
	}
	if (buf[0] != (llo = CheckSum(&cp[6], len)))
	    fprintf(stderr, "%s: Bad checksum (%d should be %d)\n",
	     av0, buf[0], llo);
	if (buf[1] != SX_EOB)
	    fprintf(stderr, "%s: Missing SX_EOB\n", av0);
	return(1);
}

use()
{
	fprintf(stderr, "Usage: %s [-pCHAN=FILE ...] [-vCHAN=FILE ...]\n", av0);
	fprintf(stderr, "CHAN is a decimal number, 1-16\n");
	fprintf(stderr, "FILE is a filename, '-' represents stdin\n");
	fprintf(stderr, "for example:\n");
	fprintf(stderr, "% %s -v9=V.Bell -p9=p.2.9 -v1=V.Piano\n", av0);
	exit(2);
}
