[comp.sources.atari.st] v01i091: mt32edit -- Patch editor for MT32 synthesizer

koreth@ssyx.ucsc.edu (Steven Grimm) (01/19/89)

Submitted-by: kurth@sco.com (Kurt Hutchinson)
Posting-number: Volume 1, Issue 91
Archive-name: mt32edit

#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
#	Run the following text with /bin/sh to create:
#	  keys.c
#	  memcpy.s
#	  mt.c
#	  mt.h
#	  mtscrn.c
#	  mtscrn.h
#	  mttype.h
#	  osbind.h
#	  patch.c
#	  patchtmp.c
#	  setuptmp.c
#	  src.c
#	  stdio.h
#	  system.c
#	  timbre.c
#	  top.c
#	  makefile
#	  mt32.doc
#
echo "x - extracting keys.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > keys.c &&
X#include <osbind.h>
X#include "mt.h"
X
X/*
X * keyboard to midi translator
X */
X
Xunsigned char midichan;
X
X/* note on, note #, note intensity */
Xunsigned char mtnote[3] = { 0x92, 0x00, 0x7d };
Xunsigned char mtnoteoff[3] = { 0xb2, 0x7b, 0x00 };
X
Xmtkeys(l)
Xlong l;
X{
X	int k;
X	int in;
X
X	k = l>>16;
X	if (k == 0x62) {
X		help();
X		return;
X	}
X	mtnote[1] = 0;
X	in = 0;
X	k = l&0x7f;
X	switch (k) {
X	case '?':
X		help();
X		return;
X	case '1':
X		in = 0x07;
X		break;
X	case '2':
X		in = 0x17;
X		break;
X	case '3':
X		in = 0x37;
X		break;
X	case '4':
X		in = 0x47;
X		break;
X	case '5':
X		in = 0x57;
X		break;
X	case '6':
X		in = 0x67;
X		break;
X	case '7':
X		in = 0x77;
X		break;
X	case '8':
X		in = 0x7f;
X		break;
X	case 'q':
X		mtnote[1] = 24;		/* C */
X		break;
X	case 'w':
X		mtnote[1] = 28;		/* E */
X		break;
X	case 'e':
X		mtnote[1] = 31;		/* G */
X		break;
X	case 'r':
X		mtnote[1] = 36;		/* C */
X		break;
X	case 't':
X		mtnote[1] = 40;		/* E */
X		break;
X	case 'y':
X		mtnote[1] = 43;		/* G */
X		break;
X	case 'u':
X		mtnote[1] = 48;		/* C */
X		break;
X	case 'i':
X		mtnote[1] = 52;		/* E */
X		break;
X	case 'o':
X		mtnote[1] = 55;		/* G */
X		break;
X	case 'p':
X		mtnote[1] = 60;		/* C */
X		break;
X	case '[':
X		mtnote[1] = 64;		/* E */
X		break;
X	case ']':
X		mtnote[1] = 67;		/* G */
X		break;
X	case 'a':
X		mtnote[1] = 72;		/* C */
X		break;
X	case 's':
X		mtnote[1] = 76;		/* E */
X		break;
X	case 'd':
X		mtnote[1] = 79;		/* G */
X		break;
X	case 'f':
X		mtnote[1] = 84;		/* C */
X		break;
X	case 'g':
X		mtnote[1] = 88;		/* E */
X		break;
X	case 'h':
X		mtnote[1] = 91;		/* G */
X		break;
X	case 'j':
X		mtnote[1] = 96;		/* C */
X		break;
X	case 'k':
X		mtnote[1] = 100;	/* E */
X		break;
X	case 'l':
X		mtnote[1] = 103;	/* G */
X		break;
X	case ';':
X		mtnote[1] = 108;	/* C */
X		break;
X	case ' ':
X		mtnoteoff[0] &= 0xf0;
X		mtnoteoff[0] |= midichan;
X		Midiws(3, mtnoteoff);
X		return;
X	}
X	if (in)
X		mtnote[2] = in;
X	if (mtnote[1]) {
X		mtnote[0] &= 0xf0;
X		mtnote[0] |= midichan;
X		Midiws(3, mtnote);
X	}
X}
X
Xhelp()
X{
X	kclear();
Xprintf("F1 to F10 are -16, -8, -4, -2, -1, +1, +2, +4, +8, +16 respectively\n");
Xprintf("Arrow keys select field\n");
Xprintf("Escape goes to previous level\n");
Xprintf("Enter takes selected action or previous level\n");
Xprintf("\nMidi test Bed only works on numeric fields\n");
Xprintf("keys 1 to 8 select intensity\n");
Xprintf("keys q-] and a-; are all notes in the C arpeggio\n");
X	printf("\n\tenter any key to continue\n");
X	while (Bconstat(CON));
X		Bconin(CON);
X	drawscrn();
X}
SHAR_EOF
chmod 0444 keys.c || echo "restore of keys.c fails"
echo "x - extracting memcpy.s (Text)"
sed 's/^X//' << 'SHAR_EOF' > memcpy.s &&
X	.shri
X	.globl	memcpy_
Xmemcpy_:
X	link	a6, $0
X	movea.l	8(a6), a0
X	movea.l	12(a6), a1
X	clr.l	d0
X	move.w	16(a6), d0
X	cmpi.l	$15, d0
X	bgt	long
Xtop:
X	subq.l	$1, d0
Xloop:
X	move.b	(a0)+, (a1)+
X	dbf	d0, loop
Xdone:
X	unlk	a6
X	rts
X
Xlong:
X	move.l	a0, d1
X	move.l	a1, d2
X	btst	$0, d1
X	beq	z1
X	btst	$0, d2
X	beq	loop
X	move.b	(a0)+, (a1)+	/ both odd
X	subq.l	$1, d0
Xaligned:
X	move.l	d0, d1
X	lsr.l	$2, d1		/ long word count
X	subq.l	$1, d1
Xlloop:
X	move.l	(a0)+, (a1)+
X	dbf	d1, lloop
X	andi.l	$3, d0
X	beq	done
X	jmp	top
X
Xz1:
X	btst	$0, d2
X	beq	aligned
X	jmp	loop
X SHAR_EOF
chmod 0444 memcpy.s || echo "restore of memcpy.s fails"
echo "x - extracting mt.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > mt.c &&
Xmain()
X{
X	top();
X}
SHAR_EOF
chmod 0444 mt.c || echo "restore of mt.c fails"
echo "x - extracting mt.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > mt.h &&
X#define CON	2
X#define MIDI	3
X#define RQMAX	16400
X
X#define uchar	unsigned char
X#define uint	unsigned int
SHAR_EOF
chmod 0444 mt.h || echo "restore of mt.h fails"
echo "x - extracting mtscrn.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > mtscrn.c &&
X#include <osbind.h>
X#include "mt.h"
X#include "mtscrn.h"
X
Xscreen_t *csp;		/* current screen */
Xint cfld;		/* current field index */
Xuchar sbuf[81];		/* ascii field data buffer */
Xint cindex;		/* current index into an ascii field */
X
Xscreen(sp)
Xregister screen_t *sp;
X{
X	csp = sp;
X	drawscrn();
X
X	scrinput();
X}
X
Xscrinput()
X{
X	register screen_t *sp;
X	register field_t *fp;
X	uchar *cp;	
X	register int c;
X	long l;
X
X	midiflush();
X	setfld(csp->s_fp);
X	for (;;) {
X		while (Bconstat(CON) == 0) { /* midi pass thru feature */
X			if (Bconstat(MIDI)) {
X				c = Bconin(MIDI);
X				Bconout(MIDI, c);
X			}
X		}
X		l = Bconin(CON);	/* we have a character to read */
X		if ((l&0xff) == 0x1b) {	/* escape is no write */
X			return(-1);
X		}
X		sp = csp;
X		fp = &sp->s_fp[cfld];
X		c = (l>>16)&0xff;
X		switch (c) {
X		case 0x1c:	/* enter done with screen */
X			(*sp->s_done)();
X			return(0);
X		case 0x4b:	/* left arrow */
X			if (cfld)
X				fp--;
X			setfld(fp);
X			continue;
X		case 0x48:	/* up arrow */
X			c = fp->f_y;
X			while (cfld) {
X				fp--;
X				cfld--;
X				if (fp->f_y < c)
X					break;
X			}
X			while (cfld) {
X				if ((fp-1)->f_y == fp->f_y) {
X					fp--;
X					cfld--;
X				}
X				else
X					break;
X			}
X			setfld(fp);
X			continue;
X		case 0x4d:	/* right arrow */
X			if ((cfld + 1) < sp->s_fieldsiz)
X				fp++;
X			setfld(fp);
X			continue;
X		case 0x50:	/* down arrow */
X			c = fp->f_y;
X			while ((cfld + 1) < sp->s_fieldsiz) {
X				fp++;
X				cfld++;
X				if (fp->f_y > c)
X					break;
X			}
X			setfld(fp);
X			continue;
X		}
X		if (fp->f_type == 1) {	/* ascii field */
X			c = l&0x7f;
X			if ((c >= 'a' && c <= 'z') ||
X				(c >= 'A' && c <= 'Z') ||
X				(c >= '0' && c <= '9') ||
X				(c == '.') || (c == ' ')) {
X				cp = (*sp->s_get)(fp->f_disp);
X				*(cp + cindex) = c;
X				if ((cindex + 1) < fp->f_len)
X					cindex++;
X				(*sp->s_put)(fp->f_disp);
X			}
X			else {
X				(*sp->s_ukn)(l);
X				continue;
X			}
X		}
X		else {			/* numeric field */
X			switch (c) {
X			case 0x3b:	/* F1 */
X				fchange(-16);
X				break;
X			case 0x3c:	/* F2 */
X				fchange(-8);
X				break;
X			case 0x3d:	/* F3 */
X				fchange(-4);
X				break;
X			case 0x3e:	/* F4 */
X				fchange(-2);
X				break;
X			case 0x3f:	/* F5 */
X				fchange(-1);
X				break;
X			case 0x40:	/* F6 */
X				fchange(1);
X				break;
X			case 0x41:	/* F7 */
X				fchange(2);
X				break;
X			case 0x42:	/* F8 */
X				fchange(4);
X				break;
X			case 0x43:	/* F9 */
X				fchange(8);
X				break;
X			case 0x44:	/* F10 */
X				fchange(16);
X				break;
X			default:
X				(*sp->s_ukn)(l);
X				continue;
X			}
X		}
X		drawfield(fp);
X		ksetcrsr(fp->f_x + cindex, fp->f_y);
X	}
X}
X
Xfchange(change)
X{
X	register screen_t *sp;
X	register field_t *fp;
X	register uchar *cp;
X	int c;
X
X	sp = csp;
X	fp = &sp->s_fp[cfld];
X	cp = (*sp->s_get)(fp->f_disp);
X	c = *cp + change;
X	if (c < 0)
X		c = 0;
X	if (c > fp->f_max)
X		c = fp->f_max;
X	*cp = c;
X	(*sp->s_put)(fp->f_disp);
X}
X
Xsetfld(fp)
Xregister field_t *fp;
X{
X	cindex = 0;
X	cfld = fp - csp->s_fp;
X	ksetcrsr(fp->f_x, fp->f_y);
X}
X
Xdrawscrn()
X{
X	kclear();
X	drawdata();
X	drawflds();
X}
X
Xdrawdata()
X{
X	register screen_t *sp;
X	register data_t *dp;
X	register int i;
X
X	sp = csp;
X	dp = sp->s_dp;
X	for (i = 0; i < sp->s_datasiz; i++) {
X		ksetcrsr(dp->d_x, dp->d_y);
X		kouts(dp->d_cp);
X		dp++;
X	}
X}
X
Xdrawflds()
X{
X	register screen_t *sp;
X	register field_t *fp;
X	register int i;
X
X	sp = csp;
X	fp = sp->s_fp;
X	for (i = 0; i < sp->s_fieldsiz; i++) {
X		drawfield(fp);
X		fp++;
X	}
X}
X
Xdrawfield(fp)
Xregister field_t *fp;
X{
X	register screen_t *sp;
X	uchar *cp;
X	int t;
X	int i;
X
X	sp = csp;
X	ksetcrsr(fp->f_x, fp->f_y);
X	switch (fp->f_type) {
X	case 2:			/* binary */
X		cp = (*sp->s_get)(fp->f_disp);
X		t = *cp + fp->f_offset;
X		cp = sbuf + fp->f_len - 1;
X		for (i = 0; i < fp->f_len; i++) {
X			if ((t & 1) == 0)
X				*cp-- = '0';
X			else
X				*cp-- = '1';
X			t >>= 1;
X		}
X		sbuf[fp->f_len] = 0;
X		break;
X	case 1:			/* ascii */
X		cp = (*sp->s_get)(fp->f_disp);
X		memcpy(cp, sbuf, fp->f_len);
X		sbuf[fp->f_len] = 0;
X		pad(sbuf, fp->f_len);
X		break;
X	case 0:			/* decimal */
X		cp = (*sp->s_get)(fp->f_disp);
X		t = *cp + fp->f_offset;
X		sprintf(sbuf, "%d", t);
X		sbuf[fp->f_len] = 0;
X		pad(sbuf, fp->f_len);
X	}
X	kouts(sbuf);
X}
X
Xkclear()
X{
X	Bconout(CON, 0x1b);
X	Bconout(CON, 'E');
X}
X
Xksetcrsr(x, y)
X{
X	Bconout(CON, 0x1b);
X	Bconout(CON, 'Y');
X	Bconout(CON, y + 0x20);
X	Bconout(CON, x + 0x20);
X}
X
Xkoutc(c)
X{
X	Bconout(CON, c);
X}
X
Xkouts(cp)
Xregister uchar *cp;
X{
X	while (*cp)
X		Bconout(CON, *cp++);
X}
X
Xpad(cp, len)
Xregister uchar *cp;
X{
X	int i;
X
X	cp[len] = 0;
X	i = strlen(cp);
X	while (i < len)
X		cp[i++] = ' ';
X}
SHAR_EOF
chmod 0444 mtscrn.c || echo "restore of mtscrn.c fails"
echo "x - extracting mtscrn.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > mtscrn.h &&
X/*
X * defines for the two screen structures
X */
X
Xstruct datadef {
X	uchar	d_y;		/* x coordinate for string */
X	uchar	d_x;		/* y coordinate for string */
X	uchar	*d_cp;		/* the string itself */
X};
X
Xtypedef struct datadef data_t;
X
Xstruct fielddef {
X	uchar	f_y;		/* x coordinate of field */
X	uchar	f_x;		/* y coordinate of field */
X	uchar	f_type;		/* 0 is number, non-zero is ascii */
X	uchar	f_len;		/* field length */
X	uchar	f_max;		/* maximum value */
X	char	f_offset;	/* offset to be added before display */
X	int	f_disp;		/* displacement of data */
X};
X
Xtypedef struct fielddef field_t;
X
Xstruct screendef {
X	data_t	*s_dp;		/* data pointer */
X	int	s_datasiz;	/* size of data array */
X	field_t *s_fp;		/* field pointer */
X	int	s_fieldsiz;	/* size of field array */
X	uchar	*(*s_get)();	/* get data function */
X	int	(*s_put)();	/* put data function */
X	int	(*s_ukn)();	/* unknown character function */
X	int	(*s_done)();	/* end of screen routine */
X};
X
Xtypedef struct screendef screen_t;
SHAR_EOF
chmod 0444 mtscrn.h || echo "restore of mtscrn.h fails"
echo "x - extracting mttype.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > mttype.h &&
X/*
X * defines for the source type structure
X */
X
Xstruct mtypedef {
X	int	t_type;		/* source type */
X	int	t_psiz;		/* physical size (displacement between adjacent
X				   entries */
X	int	t_vsiz;		/* virtual size (size of read and write
X				   requests */
X	uchar	t_base[3];	/* base memory address in mt32 */
X	int	t_max;		/* max entries in mt32 memory area */
X	uchar	t_filesuf[6];	/* file suffix for this type */
X};
X
Xtypedef struct mtypedef type_t;
X
X#define T_PATCH		0	/* patch */
X#define T_PATCHTMP	1	/* patch tmp */
X#define T_TIMBRE	2	/* timbre memory */
X#define T_TIMBRETMP	3	/* timbre tmp memory */
X#define T_SYSTEM	4	/* system memory area */
X#define T_SETUPTMP	5	/* setup tmp area */
SHAR_EOF
chmod 0444 mttype.h || echo "restore of mttype.h fails"
echo "x - extracting osbind.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > osbind.h &&
X/**
X*
X* This file contains macro definitions for use with the Atari specific
X* functions gemdos,bios and xbios
X*
X**/
X
Xextern long bios();
Xextern long xbios();
Xextern long gemdos();
X
X/* GEMDOS functions (trap #1) */
X
X#define Pterm0()		gemdos(0x0)
X#define Cconin()		gemdos(0x1)
X#define Cconout(a)		gemdos(0x2,a)
X#define Cauxin()		gemdos(0x3)
X#define Cauxout(a)		gemdos(0x4,a)
X#define Cprnout(a)		gemdos(0x5,a)
X#define Crawio(a)		gemdos(0x6,a)
X#define Crawcin()		gemdos(0x7)
X#define Cnecin()		gemdos(0x8)
X#define Cconws(a)		gemdos(0x9,a)
X#define Cconrs(a)		gemdos(0x0a,a)
X#define Cconis()		gemdos(0x0b)
X#define Dsetdrv(a)		gemdos(0x0e,a)
X#define Cconos()		gemdos(0x10)
X#define Cprnos()		gemdos(0x11)
X#define Cauxis()		gemdos(0x12)
X#define Cauxos()		gemdos(0x13)
X#define Dgetdrv()		gemdos(0x19)
X#define Fsetdta(a)		gemdos(0x1a,a)
X#define Super(a)		gemdos(0x20,a)
X#define Tgetdate()		gemdos(0x2a)
X#define Tsetdate(a)		gemdos(0x2b,a)
X#define Tgettime()		gemdos(0x2c)
X#define Tsettime(a)		gemdos(0x2d,a)
X#define Fgetdta()		gemdos(0x2f)
X#define Sversion()		gemdos(0x30)
X#define Ptermres(a,b)		gemdos(0x31,a,b)
X#define Dfree(a,b)		gemdos(0x36,a,b)
X#define Dcreate(a)		gemdos(0x39,a)
X#define Ddelete(a)		gemdos(0x3a,a)
X#define Dsetpath(a)		gemdos(0x3b,a)
X#define Fcreate(a,b)		gemdos(0x3c,a,b)
X#define Fopen(a,b)		gemdos(0x3d,a,b)
X#define Fclose(a)		gemdos(0x3e,a)
X#define Fread(a,b,c)		gemdos(0x3f,a,b,c)
X#define Fwrite(a,b,c)		gemdos(0x40,a,b,c)
X#define Fdelete(a)		gemdos(0x41,a)
X#define Fseek(a,b,c)		gemdos(0x42,a,b,c)
X#define Fattrib(a,b,c)		gemdos(0x43,a,b,c)
X#define Fdup(a)			gemdos(0x45,a)
X#define Fforce(a,b)		gemdos(0x46,a,b)
X#define Dgetpath(a,b)		gemdos(0x47,a,b)
X#define Malloc(a)		gemdos(0x48,a)
X#define Mfree(a)		gemdos(0x49,a)
X#define Mshrink(a,b)		gemdos(0x4a,0,a,b)   /* NOTE: Null parameter added */
X#define Pexec(a,b,c,d)		gemdos(0x4b,a,b,c,d)
X#define Pterm(a)		gemdos(0x4c,a)
X#define Fsfirst(a,b)		gemdos(0x4e,a,b)
X#define Fsnext()		gemdos(0x4f)
X#define Frename(a,b,c)		gemdos(0x56,a,b,c)
X#define Fdatime(a,b,c)		gemdos(0x57,a,b,c)
X
X/* BIOS functions (trap #13) */
X
X#define	Getmpb(a)		bios(0,a)
X#define Bconstat(a)		bios(1,a)
X#define Bconin(a)		bios(2,a)
X#define Bconout(a,b)		bios(3,a,b)
X#define Rwabs(a,b,c,d,e)	bios(4,a,b,c,d,e)
X#define Setexc(a,b)		bios(5,a,b)
X#define	Tickcal()		bios(6)
X#define	Getbpb(a)		bios(7,a)
X#define Bcostat(a)		bios(8,a)
X#define Mediach(a)		bios(9,a)
X#define Drvmap()		bios(10)
X#define Getshift(a)		bios(11,a)
X
X/* XBIOS functions (trap #14) */
X
X#define Initmous(a,b,c)		(void) xbios(0,a,b,c)
X#define Physbase()              (char *) xbios(2)
X#define Logbase()               (char *) xbios(3)
X#define Getrez()                (int) xbios(4)
X#define Setscreen(a,b,c)        (void) xbios(5,a,b,c)
X#define Setpallete(a)           (void) xbios(6,a)
X#define Setcolor(a,b)           (int) xbios(7,a,b)
X#define Floprd(a,b,c,d,e,f,g)   (int) xbios(8,a,b,c,d,e,f,g)
X#define Flopwr(a,b,c,d,e,f,g)   (int) xbios(9,a,b,c,d,e,f,g)
X#define	Flopfmt(a,b,c,d,e,f,g,h,i) (int) xbios(10,a,b,c,d,e,f,g,h,i)
X/* XBIOS function 11 is unused */
X#define Midiws(a,b)		(void) xbios(12,a,b)
X#define Mfpint(a,b)		(void) xbios(13,a,b)
X#define Iorec(a)		(char *) xbios(14,a)
X#define Rsconf(a,b,c,d,e,f)	(void) xbios(15,a,b,c,d,e,f)
X#define Keytbl(a,b,c)		(char *) xbios(16,a,b,c)
X#define Random()		xbios(17)
X#define Protobt(a,b,c,d)	(void) xbios(18,a,b,c,d)
X#define Flopver(a,b,c,d,e,f,g)	(int) xbios(19,a,b,c,d,e,f,g)
X#define Scrdmp()		(void) xbios(20)
X#define Cursconf(a,b)		(int) xbios(21,a,b)
X#define Settime(a)		(void) xbios(22,a)
X#define Gettime()		xbios(23)
X#define Bioskeys()		(void) xbios(24)
X#define Ikbdws(a,b)		(void) xbios(25,a,b)
X#define Jdisint(a)		(void) xbios(26,a)
X#define Jenabint(a)		(void) xbios(27,a)
X#define Giaccess(a,b)		(char) xbios(28,a,b)
X#define Offgibit(a)		(void) xbios(29,a)
X#define Ongibit(a)		(void) xbios(30,a)
X#define Xbtimer(a,b,c,d)	(void) xbios(31,a,b,c,d)
X#define Dosound(a)		(void) xbios(32,a)
X#define Setprt(a)		(int) xbios(33,a)
X#define Kbdvbase()		(char **) xbios(34)
X#define Kbrate(a,b)		(int) xbios(35,a,b)
X#define Prtblk(a)		(int) xbios(36,a)
X#define	Vsync()			(void) xbios(37)
X#define	Supexec(a)		(unsigned long) xbios(38,a)
X#define	Puntaes()		(void) xbios(39)
SHAR_EOF
chmod 0444 osbind.h || echo "restore of osbind.h fails"
echo "x - extracting patch.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > patch.c &&
X#include "mt.h"
X#include "mtscrn.h"
X
Xuchar *mtgetdata();
Xint mtputdata();
Xint mtkeys();
Xint mtdone();
X
Xdata_t patchdata[] = {
X	{  1, 26, "MT32 PATCH MEMORY" },
X	{  5,  8, "Timbre Group (Group A, Group B, Memory, Rhythm)" },
X	{  5, 58, "[ ]    (1-4)" },
X	{  7,  8, "Timbre Number" },
X	{  7, 58, "[  ]   (1-64)" },
X	{  9,  8, "Key Shift" },
X	{  9, 58, "[   ]  (-24 to 24)" },
X	{ 11,  8, "Fine Tune" },
X	{ 11, 58, "[   ]  (-50 to 50)" },
X	{ 13,  8, "Bender Range (half steps)" },
X	{ 13, 58, "[  ]   (0 to 24)" },
X	{ 15,  8, "Assign Mode (single-last,s-first,multi-last,m-f)" },
X	{ 15, 58, "[ ]    (1-4)" },
X	{ 17,  8, "Reverb Switch (off, on)" },
X	{ 17, 58, "[ ]    (0-1)" }
X};
X
Xfield_t patchfield[] = {
X/*  x   y   type   len   max   offset   disp */
X{   5, 59,     0,    1,    3,       1,     0 },		/* timbre group */
X{   7, 59,     0,    2,   63,       1,     1 },		/* timbre number */
X{   9, 59,     0,    3,   48,     -24,     2 },		/* Key Shift */
X{  11, 59,     0,    3,  100,     -50,     3 },		/* Fine Tune */
X{  13, 59,     0,    2,   24,       0,     4 },		/* Bender Range */
X{  15, 59,     0,    1,    3,       1,     5 },		/* Assign Mode */
X{  17, 59,     0,    1,    1,       0,     6 }		/* Reverb Switch */
X};
X
Xscreen_t patchscrn[] = {
X	patchdata,
X	sizeof(patchdata)/sizeof(data_t),
X	patchfield,
X	sizeof(patchfield)/sizeof(field_t),
X	mtgetdata,
X	mtputdata,
X	mtkeys,
X	mtdone
X};
X
Xspatch()
X{
X	screen(patchscrn);
X}
SHAR_EOF
chmod 0444 patch.c || echo "restore of patch.c fails"
echo "x - extracting patchtmp.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > patchtmp.c &&
X#include "mt.h"
X#include "mtscrn.h"
X
Xuchar *mtgetdata();
Xint mtputdata();
Xint mtkeys();
Xint mtdone();
X
Xdata_t patchtdata[] = {
X	{  1, 26, "MT32 PATCH MEMORY" },
X	{  5,  8, "Timbre Group (Group A, Group B, Memory, Rhythm)" },
X	{  5, 58, "[ ]    (1-4)" },
X	{  7,  8, "Timbre Number" },
X	{  7, 58, "[  ]   (1-64)" },
X	{  9,  8, "Key Shift" },
X	{  9, 58, "[   ]  (-24 to 24)" },
X	{ 11,  8, "Fine Tune" },
X	{ 11, 58, "[   ]  (-50 to 50)" },
X	{ 13,  8, "Bender Range (half steps)" },
X	{ 13, 58, "[  ]   (0 to 24)" },
X	{ 15,  8, "Assign Mode (single-last,s-first,multi-last,m-f)" },
X	{ 15, 58, "[ ]    (1-4)" },
X	{ 17,  8, "Reverb Switch (off, on)" },
X	{ 17, 58, "[ ]    (0-1)" },
X	{ 19,  8, "Output level" },
X	{ 19, 58, "[   ]  (0-100)" },
X	{ 21,  8, "Panpot (Right to Left)" },
X	{ 21, 58, "[   ]  (-7 to 7)" }
X};
X
Xfield_t patchtfield[] = {
X/*  x   y   type   len   max   offset   disp */
X{   5, 59,     0,    1,    3,       1,     0 },		/* timbre group */
X{   7, 59,     0,    2,   63,       1,     1 },		/* timbre number */
X{   9, 59,     0,    3,   48,     -24,     2 },		/* Key Shift */
X{  11, 59,     0,    3,  100,     -50,     3 },		/* Fine Tune */
X{  13, 59,     0,    2,   24,       0,     4 },		/* Bender Range */
X{  15, 59,     0,    1,    3,       1,     5 },		/* Assign Mode */
X{  17, 59,     0,    1,    1,       0,     6 },		/* Reverb Switch */
X{  19, 59,     0,    3,  100,       0,     8 },		/* output level */
X{  21, 59,     0,    2,   14,      -7,     9 }		/* panpot */
X};
X
Xscreen_t patchtscrn[] = {
X	patchtdata,
X	sizeof(patchtdata)/sizeof(data_t),
X	patchtfield,
X	sizeof(patchtfield)/sizeof(field_t),
X	mtgetdata,
X	mtputdata,
X	mtkeys,
X	mtdone
X};
X
Xspatchtmp()
X{
X	screen(patchtscrn);
X}
SHAR_EOF
chmod 0444 patchtmp.c || echo "restore of patchtmp.c fails"
echo "x - extracting setuptmp.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > setuptmp.c &&
X#include "mt.h"
X#include "mtscrn.h"
X
Xdata_t setupdata[] = {
X	{  1, 32, "MT32 RHYTHM SETUP" },
X	{  3, 10, "Timbre (1-64 memory, 65-94 Rhythm, 95 = off)" },
X	{  3, 58, "[  ]" },
X	{  5, 10, "Output Level (0-100)" },
X	{  5, 57, "[   ]" },
X	{  7, 10, "Panpot (-7 to 7) Right to Left" },
X	{  7, 58, "[  ]" },
X	{  9, 10, "Reverb Switch (0-off, 1-on)" },
X	{  9, 59, "[ ]" }
X};
X
Xfield_t setupfield[] = {
X/*   y   x   type   len   max   offset   disp */
X{    3, 59,     0,    2,   94,       1,     0 },
X{    5, 58,     0,    3,  100,       0,     1 },
X{    7, 59,     0,    2,   14,      -7,     2 },
X{    9, 60,     0,    1,    1,       0,     3 }
X};
X
Xuchar *mtgetdata();
Xint mtputdata();
Xint mtkeys();
Xint mtdone();
X
Xscreen_t setupscreen = {
X	setupdata,
X	sizeof(setupdata)/sizeof(data_t),
X	setupfield,
X	sizeof(setupfield)/sizeof(field_t),
X	mtgetdata,
X	mtputdata,
X	mtkeys,
X	mtdone
X};
X
Xssetuptmp()
X{
X	screen(&setupscreen);
X}
SHAR_EOF
chmod 0444 setuptmp.c || echo "restore of setuptmp.c fails"
echo "x - extracting src.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src.c &&
X#include <osbind.h>
X#include <stdio.h>
X#include "mt.h"
X#include "mttype.h"
X
Xuchar midibuf[270];	/* the midi buffer */
Xuchar mtwork[256];	/* the workspace area */
X
Xtype_t *ctp;		/* current type pointer */
Xint centry;		/* current entry */
Xint memflg;		/* memory flag */
Xuchar outfile[15];	/* the destination file name */
X
Xlong c3tol();
X
Xuchar mtget[] = {
X	0xf0,		/* start excl */
X	0x41,		/* Roland Id */
X	0x10,		/* device 16 */
X	0x16,		/* mt32 model id */
X	0x11,		/* read command */
X	0x00,		/* address byte 2 */
X	0x00,		/* address byte 1 */
X	0x00,		/* address byte 0 */
X	0x00,		/* size byte 2 */
X	0x00,		/* size byte 1 */
X	0x00,		/* size byte 0 */
X	0x00,		/* checksum */
X	0xf7		/* excl end */
X};
X
X#define MTADDR		5
X#define MTSIZ		8
X#define MTDATA		8
X#define MTGSUM		11
X#define MTCMD		4
X#define MTSEND		0x12
X
Xtype_t typetab[] = {
X	{ T_PATCH,       8,   8,  { 0x05, 0x00, 0x00 }, 128, "ptm" },
X	{ T_PATCHTMP,   16,  16,  { 0x03, 0x00, 0x00 },   9, "ptt" },
X	{ T_TIMBRE,    256, 246,  { 0x08, 0x00, 0x00 },  64, "tmb" },
X	{ T_TIMBRETMP, 246, 246,  { 0x04, 0x00, 0x00 },   8, "tmt" },
X	{ T_SYSTEM,     24,  24,  { 0x10, 0x00, 0x00 },   1, "sys" },
X	{ T_SETUPTMP,    4,   4,  { 0x03, 0x01, 0x10 },  64, "set" }
X};
X
Xmtsrc(type, entryn)
X{
X	long addr;
X	register type_t *tp;
X	register uchar *cp;
X	int i;
X	int len;
X	int chksum;
X
X	tp = &typetab[type];
X	if (entryn < 0 || entryn > tp->t_max) {
X		printf("bad source entry number\n");
X		return(-1);
X	}
X	addr = c3tol(tp->t_base);
X	addr += entryn * tp->t_psiz;
X	ltoc3(addr, &mtget[MTADDR]);
X	ltoc3((long)tp->t_vsiz, &mtget[MTSIZ]);
X	midiflush();
X	chksum = 0;	
X	for (cp = mtget + MTADDR; cp < &mtget[sizeof(mtget) - 2]; cp++)
X		chksum += *cp;
X	mtget[MTGSUM] = (0 - chksum)&0x7f;
X	Midiws(sizeof(mtget), mtget);
X	cp = midibuf;
X	*cp = 0;
X	for (addr = 0; addr < 100000l; addr++) {
X		if (Bconstat(MIDI)) {
X			*cp = Bconin(MIDI);
X			if ((cp - midibuf) >= 255)
X				break;
X			if (*cp == 0xf7)
X				break;
X			*(++cp) = 0;
X		}
X	}
X	if (*cp != 0xf7) {
X		printf("incomplete midi message received\n");
X		return(-1);
X	}
X	len = (cp - midibuf);
X	chksum = 0;
X	for (i = MTADDR; i < len; i++)
X		chksum += midibuf[i];
X	if (chksum&0x7f)
X		return(-1);
X	len -= MTDATA;
X	memcpy(midibuf + MTDATA, mtwork, len);
X	return(0);
X}
X
Xmtsrcf(type, filename)
Xuchar *filename;
X{
X	register type_t *tp;
X	FILE *fd;
X	int len;
X
X	tp = &typetab[type];
X	strcpy(outfile, filename);
X	bstrip(outfile);
X	strcat(outfile, ".");
X	strcat(outfile, tp->t_filesuf);	/* extension */
X	fd = fopen(outfile, "rb");
X	if (fd == 0) {
X		printf("open error on %s\n", outfile);
X		return(-1);
X	}
X	len = tp->t_vsiz + 10;
X	if (fread(midibuf, 1, len, fd) != len) {
X		printf("read len error on %s\n", outfile);
X		fclose(fd);
X		return(-1);
X	}
X	fclose(fd);
X	len -= MTDATA;
X	memcpy(midibuf + MTDATA, mtwork, len);
X	return(0);
X}
X
Xmtdst(type, entryn)
X{
X	register type_t *tp;
X
X	tp = &typetab[type];
X	ctp = tp;
X	if (entryn >= tp->t_max) {
X		printf("bad dst entry number\n");
X		return(-1);
X	}
X	centry = entryn;
X	memflg = 1;
X	return(0);
X}
X
Xmtdstf(type, entryn, filename)
Xuchar *filename;
X{
X	register type_t *tp;
X
X	tp = &typetab[type];
X	ctp = tp;
X	centry = entryn;
X	memflg = 0;
X	strcpy(outfile, filename);
X	bstrip(outfile);
X	strcat(outfile, ".");
X	strcat(outfile, tp->t_filesuf);
X	return(0);
X}
X
Xlong
Xc3tol(cp)
Xuchar *cp;
X{
X	register long l;
X
X	l = 0;
X	l |= (*cp++)&0x7f;
X	l <<= 7;
X	l |= (*cp++)&0x7f;
X	l <<= 7;
X	l |= *cp&0x7f;
X	return(l);
X}
X
Xltoc3(l, cp)
Xregister long l;
Xregister uchar *cp;
X{
X	cp += 2;
X	*cp-- = l&0x7f;
X	l >>= 7;
X	*cp-- = l&0x7f;
X	l >>= 7;
X	*cp = l&0x7f;
X}
X
Xmidiflush()
X{
X	while (Bconstat(MIDI))
X		Bconin(MIDI);
X}
X
Xuchar *
Xmtgetdata(disp)
X{
X	register uchar *cp;
X
X	cp = mtwork + disp;
X	return(cp);
X}
X
Xmtputdata()
X{
X	int len;
X
X	if (memflg == 0)
X		return;
X	len = mtformat();	/* sticks msg into midibuf */
X	Midiws(len, midibuf);
X}
X
Xmtdone()
X{
X	int len;
X	FILE *fd;
X
X	if (memflg)
X		return;
X
X	len = mtformat();	/* sticks msg into midibuf */
X	fd = fopen(outfile, "wb");
X	if (fd == 0) {
X		kclear();
X		printf("open error on output file %s\n", outfile);
X		sleep(2);
X		return;
X	}
X	if (fwrite(midibuf, 1, len, fd) != len) {
X		kclear();
X		printf("write error on %s\n", outfile);
X		fclose(fd);
X		sleep(2);
X		return;
X	}
X	fclose(fd);
X	return;
X}
X
X/*
X * format an entry into midibuf for output or write to file
X */
Xmtformat()
X{
X	register type_t *tp;
X	register uchar *cp;
X	long l;
X	int chksum;
X	int len;
X
X	tp = ctp;
X	memcpy(mtget, midibuf, MTCMD);
X	midibuf[MTCMD] = MTSEND;
X	l = c3tol(tp->t_base) + (centry*tp->t_psiz);
X	ltoc3(l, midibuf + MTADDR);
X	memcpy(mtwork, midibuf + MTDATA, tp->t_vsiz);
X	chksum = 0;
X	for (cp = midibuf + MTADDR; cp < (midibuf + tp->t_vsiz + MTDATA); cp++)
X		chksum += *cp;
X	*cp++ = (0 - chksum)&0x7f;
X	*cp++ = 0xf7;
X	len = tp->t_vsiz + 10;
X	return(len);
X}
X
X/*
X * clobber everything after the first blank by changing
X * the first blank to a zero.  Blanks are ok for the roland
X * but bad for filenames
X */
Xbstrip(cp)
Xregister char *cp;
X{
X	char *index();
X	register char *cp1;
X
X	cp1 = index(cp, ' ');
X	if (cp1)
X		*cp1 = 0;
X}
SHAR_EOF
chmod 0444 src.c || echo "restore of src.c fails"
echo "x - extracting stdio.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > stdio.h &&
X/*
X * Standard I/O library for Atari ST.
X */
X
X#ifndef	STDIO_H
X#define	STDIO_H	STDIO_H
Xtypedef struct	FILE {
X	unsigned char	*_cp,		/* current character ptr */
X			*_dp,		/* ptr to start of data in buffer */
X			*_bp;		/* buffer pointer */
X	int	_cc;			/* character count */
X	int	(*_gt)(),		/* getc function */
X		(*_pt)();		/* putc function */
X	char	_ff;			/* flags; see below */
X	char	_fd;			/* file descriptor (reqd by reopen) */
X	int	_uc;			/* ungot char */
X}	FILE;
X#endif
X
X#define	NULL	((char *)0)
X#define	EOF	(-1)
X#define	BUFSIZ	(1<<9)
X#define	_NFILE	20
X
Xextern	FILE	_stdin, _stdout, _stderr, *_fp[_NFILE];
X
X/* Flags in _ff */
X#define	_FINUSE	01
X#define	_FSTBUF	02		/* setbuf was called */
X#define	_FUNGOT	04		/* ungotten char present */
X#define _FASCII	010		/* ascii mode (\r\n instead of \n) */
X#define	_FEOF	0100
X#define	_FERR	0200
X
X#define	_ep(fp)		((fp)->_bp+BUFSIZ)
X
Xchar	*gets();
Xchar	*fgets();
XFILE	*fopen();
XFILE	*freopen();
XFILE	*fdopen();
XFILE	*_stropen();
Xchar	*malloc();
Xchar	*sbrk();
Xlong	ftell();
Xvoid	puts();
Xvoid	fputs();
Xvoid	setbuf();
Xlong	bdos();
X
X#define getc(fp)	fgetc(fp)
X#define putc(c, fp)	fputc(c, fp)
X#define	getchar()	getc(stdin)
X#define	putchar(c)	putc(c, stdout)
X#define	feof(fp)	((fp)->_ff&(_FEOF|_FERR))
X#define	ferror(fp)	((fp)->_ff&_FERR)
X#define	clearerr(fp)	((fp)->_ff &= ~(_FERR|_FEOF))
X#define	fileno(fp)	((fp)->_fd)
X#define	wdleng()	(16)
X
X#define	stdin	(&_stdin)
X#define	stdout	(&_stdout)
X#define	stderr	(&_stderr)
SHAR_EOF
chmod 0444 stdio.h || echo "restore of stdio.h fails"
echo "x - extracting system.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > system.c &&
X#include "mt.h"
X#include "mtscrn.h"
X
Xuchar *mtgetdata();
Xint mtputdata();
Xint mtkeys();
Xint mtdone();
X
Xdata_t sysdata[] = {
X	{  1, 28, "MT32 System Area" },
X	{  3, 20, "Master Tune   [   ]  0 is 440, .2 hz increments" },
X	{  5, 20, "Master Volume [   ]  0 to 100" },
X	{  7,  8, "Reverb Mode (Room, Hall, Plate, Tap9 Delay)  [ ]  (0-3)" },
X	{  9,  8, "Reverb Time  [ ]  0-7" },
X	{  9, 34, "Reverb Level  [ ]  1-8" },
X	{ 11, 20, "Partial Reserves (0-32), total of 32" },
X	{ 13,  0, "ch 1 [  ] ch 2 [  ] ch 3 [  ] ch 4 [  ] ch 5 [  ]" },
X	{ 13, 50, "ch 6 [  ] ch 7 [  ] ch 8 [  ]" },
X	{ 14,  0, "Rhythm [  ]" },
X	{ 15, 16, "Midi Channel For Each Part (1-16, 17 = OFF)" },
X	{ 17,  0, "ch 1 [  ] ch 2 [  ] ch 3 [  ] ch 4 [  ] ch 5 [  ]" },
X	{ 17, 50, "ch 6 [  ] ch 7 [  ] ch 8 [  ]" },
X	{ 18,  0, "Rhythm [  ]" }
X};
X
Xfield_t sysfields[] = {
X/* y    x  type  len  max  offset  disp */
X{  3,  35,    0,   3, 127,    -64,    0 },	/* master tune */
X{  5,  35,    0,   3, 100,      0,   22 },	/* master volume */
X{  7,  54,    0,   1,   3,      0,    1 },      /* reverb mode */
X{  9,  22,    0,   1,   7,      0,    2 },      /* reverb time */
X{  9,  49,    0,   1,   7,      1,    3 },	/* reverb level */
X{  13,  6,    0,   2,  32,      0,    4 },	/* reserve ch 1 */
X{  13, 16,    0,   2,  32,      0,    5 },	/* reserve ch 2 */
X{  13, 26,    0,   2,  32,      0,    6 },	/* reserve ch 3 */
X{  13, 36,    0,   2,  32,      0,    7 },	/* reserve ch 4 */
X{  13, 46,    0,   2,  32,      0,    8 },	/* reserve ch 5 */
X{  13, 56,    0,   2,  32,      0,    9 },	/* reserve ch 6 */
X{  13, 66,    0,   2,  32,      0,   10 },	/* reserve ch 7 */
X{  13, 76,    0,   2,  32,      0,   11 },	/* reserve ch 8 */
X{  14,  8,    0,   2,  32,      0,   12 },	/* reserve rhythm */
X{  17,  6,    0,   2,  16,      1,   13 },      /* midi channel 1 */
X{  17, 16,    0,   2,  16,      1,   14 },      /* midi channel 2 */
X{  17, 26,    0,   2,  16,      1,   15 },      /* midi channel 3 */
X{  17, 36,    0,   2,  16,      1,   16 },      /* midi channel 4 */
X{  17, 46,    0,   2,  16,      1,   17 },      /* midi channel 5 */
X{  17, 56,    0,   2,  16,      1,   18 },      /* midi channel 6 */
X{  17, 66,    0,   2,  16,      1,   19 },      /* midi channel 6 */
X{  17, 76,    0,   2,  16,      1,   20 },      /* midi channel 7 */
X{  18,  8,    0,   2,  16,      1,   21 }       /* midi channel R */
X};
X
Xscreen_t sysscreen = {
X	sysdata,
X	sizeof(sysdata)/sizeof(data_t),
X	sysfields,
X	sizeof(sysfields)/sizeof(field_t),
X	mtgetdata,
X	mtputdata,
X	mtkeys,
X	mtdone
X};
X
Xssystem()
X{
X	screen(&sysscreen);
X}
SHAR_EOF
chmod 0444 system.c || echo "restore of system.c fails"
echo "x - extracting timbre.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > timbre.c &&
X#include "mt.h"
X#include "mtscrn.h"
X
X#define TDATASIZ	(sizeof(timbredata))
X#define TDATAS		(TDATASIZ/sizeof(data_t))
X#define TFIELDSIZ	(sizeof(timbrefield))
X#define TFIELDS		(TFIELDSIZ/sizeof(field_t))
X#define TSCREENSIZ	(sizeof(timbrescreen))
X
Xuchar *mtgetdata();
Xint mtputdata();
Xint mtkeys();
Xint mtdone();
X
Xextern uchar mtwork[];
X
Xdata_t timbredata[] = {
X{  0,  0, "WAVE GENERATOR:" },
X{  0, 26, "Pitch Coarse (0-96)   [  ]  Pitch Fine (-50-50) [   ]" },
X{  1,  0, "Keyfollow (-3-12)  [   ]" },
X{  1, 26, "Pitch Bender enable    [ ]  Waveform 1-SQ 2-SAW   [ ]" },
X{  2,  0, "PCM Sample # 1-128 [   ]" },
X{  2, 26, "Pulse Width (0-100)  [   ]  WG Velo Sense (-7-7) [  ]" },
X{  4,  0, "PITCH ENVELOPE:" },
X{  4, 26, "Depth  (0-10)         [  ]  Velo Sense (0-100)  [   ]" },
X{  5,  0, "Time Keyfollow (0-4) [ ]" },
X{  5, 26, "Time 1 (0-100)       [   ]  Time 2 (0-100)      [   ]" },
X{  6,  0, "Time 3 (0-100)     [   ]" },
X{  6, 26, "Time 4 (0-100)       [   ]  Level 0 (-50-50)    [   ]" },
X{  7,  0, "Level 1 (-50-50)   [   ]" },
X{  7, 26, "Level 2 (-50-50)     [   ]  Sustain (-50-50)    [   ]" },
X{  8,  0, "End Level (-50-50) [   ]" },
X{  9,  0, "P-LFO Rate (0-100) [   ]" },
X{  9, 26, "P-LFO Depth (0-100)  [   ]  P-LFO Mod Sens 0-100[   ]" },
X{ 11,  0, "TIME VARIABLE FILTER:" },
X{ 11, 26, "Cutoff Freq (0-100)  [   ]  Resonance (0-30)     [  ]" },
X{ 12,  0, "Keyfollow (-3-12)   [  ]" },
X{ 12, 26, "Bias Point (-64-64)  [   ]  Bias Level (-7-7)    [  ]" },
X{ 13,  0, "Env Depth (0-100)  [   ]" },
X{ 13, 26, "Velo Sens (0-100)    [   ]  Depth Keyfollow 0-4   [ ]" },
X{ 14,  0, "Time Keyfollow 0-4   [ ]" },
X{ 14, 26, "Time 1 (0-100)       [   ]  Time 2 (0-100)      [   ]" },
X{ 15,  0, "Time 3 (0-100)     [   ]" },
X{ 15, 26, "Time 4 (0-100)       [   ]  Time 5 (0-100)      [   ]" },
X{ 16,  0, "Level 1 (0-100)    [   ]" },
X{ 16, 26, "Level 2 (0-100)      [   ]  Level 3 (0-100)     [   ]" },
X{ 17,  0, "Sustain (0-100)    [   ]" },
X{ 19,  0, "TIME VARIABLE AMPLIFIER:" },
X{ 19, 26, "Level (0-100)        [   ]  Velo Sens (0-100)   [   ]" },
X{ 20,  0, "Bias 1 Point -64-64[   ]" },
X{ 20, 26, "Bias 1 Level (-12-0) [   ]  Bias 2 Point -64-64 [   ]" },
X{ 21,  0, "Bias 2 Level -12-0 [   ]" },
X{ 21, 26, "Time Keyfollow (0-4)   [ ]  Time Velo Follow 0-4  [ ]" },
X{ 22,  0, "Time 1 (0-100)     [   ]" },
X{ 22, 26, "Time 2 (0-100)       [   ]  Time 3 (0-100)      [   ]" },
X{ 23,  0, "Time 4 (0-100)     [   ]" },
X{ 23, 26, "Time 5 (0-100)       [   ]  Level 1 (0-100)     [   ]" },
X{ 24,  0, "Level2 (0-100)     [   ]" },
X{ 24, 26, "Level 3 (0-100)      [   ]  Sustain (0-100)     [   ]" }
X};
X
Xfield_t timbrefield[] = {
X/*   y   x   type   len   max   offset   disp */
X{    0, 49,     0,    2,   96,       0,     0 },	/* pitch coarse */
X{    0, 75,     0,    3,  200,     -50,     1 },	/* pitch fine */
X{    1, 20,     0,    3,   16,      -3,     2 },	/* keyfollow */
X{    1, 50,     0,    1,    1,       0,     3 },	/* Bender enable */
X{    1, 77,     0,    1,    1,       1,     4 },	/* Waveform */
X{    2, 20,     0,    3,  127,       1,     5 },	/* PCM # */
X{    2, 48,     0,    3,  100,       0,     6 },	/* Pulse Width */
X{    2, 76,     0,    2,   14,      -7,     7 },	/* WG velo sens */
X/* P-ENVELOPE Generator */
X{    4, 49,     0,    2,   10,       0,     8 },	/* P-env Depth */
X{    4, 75,     0,    3,  100,       0,     9 },	/* Velo Sens */
X{    5, 22,     0,    1,    4,       0,  0x0a },	/* time keyfollow */
X{    5, 48,     0,    3,  100,       0,  0x0b },	/* Time 1 */
X{    5, 75,     0,    3,  100,       0,  0x0c },	/* time 2 */
X{    6, 20,     0,    3,  100,       0,  0x0d },	/* time 3 */
X{    6, 48,     0,    3,  100,       0,  0x0e },	/* time 4 */
X{    6, 75,     0,    3,  100,     -50,  0x0f },	/* level 0 */
X{    7, 20,     0,    3,  100,     -50,  0x10 },	/* level 1 */
X{    7, 48,     0,    3,  100,     -50,  0x11 },	/* level 2 */
X{    7, 75,     0,    3,  100,     -50,  0x12 },	/* sustain */
X{    8, 20,     0,    3,  100,     -50,  0x13 },	/* End Level */
X{    9, 20,     0,    3,  100,       0,  0x14 },	/* P-LFO Rate */
X{    9, 48,     0,    3,  100,       0,  0x15 },	/* P-LFO Depth */
X{    9, 75,     0,    3,  100,       0,  0x16 },	/* P-LFO Mod sens */
X/* Time Variable Filter */
X{   11, 48,     0,    3,  100,       0,  0x17 },	/* Cutoff Freq */
X{   11, 76,     0,    2,   30,       0,  0x18 },        /* Resonance */
X{   12, 21,     0,    2,   16,      -3,  0x19 },	/* Keyfollow */
X{   12, 48,     0,    3,  127,     -64,  0x1a },	/* bias point */
X{   12, 76,     0,    2,   14,      -7,  0x1b },	/* bias level */
X{   13, 20,     0,    3,  100,       0,  0x1c },	/* envelope depth */
X{   13, 48,     0,    3,  100,       0,  0x1d },	/* Velo Sens */
X{   13, 77,     0,    1,    4,       0,  0x1e },	/* Depth keyf */
X{   14, 22,     0,    1,    4,       0,  0x1f },	/* Time keyf */
X{   14, 48,     0,    3,  100,       0,  0x20 },	/* Time 1 */
X{   14, 75,     0,    3,  100,       0,  0x21 },	/* Time 2 */
X{   15, 20,     0,    3,  100,       0,  0x22 },	/* Time 3 */
X{   15, 48,     0,    3,  100,       0,  0x23 },	/* Time 4 */
X{   15, 75,     0,    3,  100,       0,  0x24 },	/* Time 5 */
X{   16, 20,     0,    3,  100,       0,  0x25 },	/* Level 1 */
X{   16, 48,     0,    3,  100,       0,  0x26 },	/* Level 2 */
X{   16, 75,     0,    3,  100,       0,  0x27 },	/* Level 3 */
X{   17, 20,     0,    3,  100,       0,  0x28 },	/* Sustain */
X/* Time Variable Amplifier */
X{   19, 48,     0,    3,  100,       0,  0x29 },	/* Main level */
X{   19, 75,     0,    3,  100,       0,  0x2a },	/* Velo Sens */
X{   20, 20,     0,    3,  127,     -64,  0x2b },	/* Bias 1 point */
X{   20, 48,     0,    3,   12,     -12,  0x2c },	/* Bias 1 level */
X{   20, 75,     0,    3,  127,     -64,  0x2d },	/* Bias 2 point */
X{   21, 20,     0,    3,   12,     -12,  0x2e },	/* Bias 2 level */
X{   21, 50,     0,    1,    4,       0,  0x2f },	/* Time keyfollow */
X{   21, 77,     0,    1,    4,       0,  0x30 },	/* Time velo keyf */
X{   22, 20,     0,    3,  100,       0,  0x31 },	/* Time 1 */
X{   22, 48,     0,    3,  100,       0,  0x32 },	/* Time 2 */
X{   22, 75,     0,    3,  100,       0,  0x33 },	/* Time 3 */
X{   23, 20,     0,    3,  100,       0,  0x34 },	/* Time 4 */
X{   23, 48,     0,    3,  100,       0,  0x35 },	/* Time 5 */
X{   23, 75,     0,    3,  100,       0,  0x36 },	/* Level 1 */
X{   24, 20,     0,    3,  100,       0,  0x37 },	/* Level 2 */
X{   24, 48,     0,    3,  100,       0,  0x38 },	/* Level 3 */
X{   24, 75,     0,    3,  100,       0,  0x39 }		/* Sustain */
X};
X
Xscreen_t timbrescreen = {
X	timbredata,
X	sizeof(timbredata)/sizeof(data_t),
X	timbrefield,
X	sizeof(timbrefield)/sizeof(field_t),
X	mtgetdata,
X	mtputdata,
X	mtkeys,
X	mtdone
X};
X
Xdata_t tdtmp[TDATAS];
Xfield_t tftmp[TFIELDS];
Xscreen_t tstmp;
X
Xdata_t commondata[] = {
X	{  1, 30, "MT32 Timbre Common Area" },
X	{  4, 20, "Tone Name   [" },
X	{  4, 43, "]" },
X	{  6, 20, "Structure Partials 1 and 2 (1-13)       [  ]" },
X	{  8, 20, "Structure Partials 3 and 4 (1-13)       [  ]" },
X	{ 10, 20, "Partial Mute (T4, T3, T2, T1)           [    ]" },
X	{ 12, 20, "Envelope Mode (0-normal, 1-no sustain)  [ ]" },
X	{ 14, 20, "Partial to edit (0-none, 1-4)           [ ]" }
X};
X
Xfield_t commonfield[] = {
X/*   y   x   type   len   max   offset   disp */
X{    4, 33,     1,   10,    0,       0,     0 },	/* tone name */
X{    6, 61,     0,    2,   12,       1,    10 },	/* structure 1&2 */
X{    8, 61,     0,    2,   12,       1,    11 },	/* structure 3&4 */
X{   10, 61,     2,    4,   16,       0,    12 },	/* Mute */
X{   12, 61,     0,    1,    1,       0,    13 },	/* envelope mode */
X{   14, 61,     0,    1,    4,       0,    250 }	/* partial to edit */
X};
X
Xscreen_t commonscreen = {
X	commondata,
X	sizeof(commondata)/sizeof(data_t),
X	commonfield,
X	sizeof(commonfield)/sizeof(field_t),
X	mtgetdata,
X	mtputdata,
X	mtkeys,
X	mtdone
X};
X
Xstimbre()
X{
X	int s;
X	register field_t *fp;
X
X	mtwork[250] = 0;		/* partial to edit */
X	for (;;) {
X		if (screen(&commonscreen) < 0)
X			return;
X		switch (s = mtwork[250]) {
X		case 0:			/* no partial edits */
X			return;
X		case 1:
X		case 2:
X		case 3:
X		case 4:
X			s--;
X			s *= 58;		/* timbre data area */
X			s += 0x0e;		/* common data size */
X			memcpy(timbredata, tdtmp, TDATASIZ);
X			memcpy(timbrefield, tftmp, TFIELDSIZ);
X			memcpy(&timbrescreen, &tstmp, TSCREENSIZ);
X			tstmp.s_dp = tdtmp;
X			tstmp.s_fp = tftmp;
X			for (fp = tftmp; fp < &tftmp[TFIELDS]; fp++)
X				fp->f_disp += s;
X			screen(&tstmp);
X		}
X	}
X}
SHAR_EOF
chmod 0444 timbre.c || echo "restore of timbre.c fails"
echo "x - extracting top.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > top.c &&
X#include <osbind.h>
X#include "mt.h"
X#include "mtscrn.h"
X#include "mttype.h"
X
Xuchar srctype;
Xuchar dsttype;
Xuchar srcentry;
Xuchar dstentry;
Xuchar srcfile[9];
Xuchar dstfile[9];
Xuchar edittype;
Xuchar midichan = 1;
X
Xdata_t topdata[] = {
X	{ 1, 26, "MT32 Patch Editor" },
X	{ 5, 12, "Src Type   [ ]  Entry #  [   ]  Src File  [" },
X	{ 5, 63, "]" },
X	{ 7, 12, "Dst Type   [ ]  Entry #  [   ]  Dst File  [" },
X	{ 7, 63, "]" },
X	{ 9, 16, "Type  1 - File" },
X	{ 9, 40, "Midi Test Channel (1-16) [  ]" },
X	{ 10, 22, "2 - MT32 Memory" },
X	{ 12, 12, "Edit Type  [ ]    1 - Patch      (*.ptm)" },
X	{ 13, 30, "2 - Patch Tmp  (*.ptt)" },
X	{ 14, 30, "3 - Timbre     (*.tmb)" },
X	{ 15, 30, "4 - Timbre Tmp (*.tmt)" },
X	{ 16, 30, "5 - System     (*.sys)" },
X	{ 17, 30, "6 - Setup Tmp  (*.set)" },
X	{ 18, 30, "7 - Exit" }
X};
X
Xfield_t topfield[] = {
X	{ 5, 24, 0, 1, 1, 1, 0 },
X	{ 5, 38, 0, 3, 127, 1, 1 },
X	{ 5, 55, 1, 8, 0, 0, 2 },
X	{ 7, 24, 0, 1, 1, 1, 3 },
X	{ 7, 38, 0, 3, 127, 1, 4 },
X	{ 7, 55, 1, 8, 0, 0, 5 },
X	{ 9, 66, 0, 2, 16, 1, 7 },
X	{ 12, 24, 0, 1, 6, 1, 6 }
X};
X
Xuchar *topget();
Xint topput();
Xint mtkeys();
X
Xscreen_t topscrn = {
X	topdata,
X	sizeof(topdata)/sizeof(data_t),
X	topfield,
X	sizeof(topfield)/sizeof(field_t),
X	topget,
X	topput,
X	mtkeys,
X	topput
X};
X
Xtop()
X{
X	int ret;
X
X	edittype = 6;
X	for (;;) {
X		if (screen(&topscrn) < 0)
X			break;
X		if (edittype == 6)
X			break;
X		ksetcrsr(0, 20);
X		if (srctype == 0)	/* file */
X			ret = mtsrcf(edittype, srcfile);
X		else
X			ret = mtsrc(edittype, srcentry);
X		if (ret == -1) {
X			sleep(1);
X			continue;
X		}
X		if (dsttype == 0)	/* file */
X			ret = mtdstf(edittype, dstentry, dstfile);
X		else
X			ret = mtdst(edittype, dstentry);
X		if (ret == -1) {
X			sleep(1);
X			continue;
X		}
X		switch (edittype) {
X		case T_PATCH:			/* patch */
X			spatch();
X			break;
X		case T_PATCHTMP:		/* patch tmp */
X			spatchtmp();
X			break;
X		case T_TIMBRE:			/* timbre */
X		case T_TIMBRETMP:		/* timbre tmp */
X			stimbre();
X			break;
X		case T_SYSTEM:			/* system */
X			ssystem();
X			break;
X		case T_SETUPTMP:		/* setup tmp */
X			ssetuptmp();
X			break;
X		}
X	}
X	ksetcrsr(0, 23);
X	exit(0);
X}
X
Xuchar *
Xtopget(disp)
X{
X	switch (disp) {
X	case 0:
X		return(&srctype);
X		break;
X	case 1:
X		return(&srcentry);
X		break;
X	case 2:
X		return(srcfile);
X		break;
X	case 3:
X		return(&dsttype);
X		break;
X	case 4:
X		return(&dstentry);
X		break;
X	case 5:
X		return(dstfile);
X		break;
X	case 6:
X		return(&edittype);
X		break;
X	case 7:
X		return(&midichan);
X		break;
X	default:
X		printf("error\n");
X		exit(0);
X	}
X}
X
Xtopput()
X{
X}
X
SHAR_EOF
chmod 0444 top.c || echo "restore of top.c fails"
echo "x - extracting makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > makefile &&
XSRC =	makefile \
X	mt.h \
X	mtscrn.h \
X	mt.c \
X	mtscrn.c \
X	top.c \
X	src.c \
X	patch.c \
X	patchtmp.c \
X	timbre.c \
X	system.c \
X	setuptmp.c \
X	mttype.h \
X	keys.c
X
XOBJS =	mt.o \
X	mtscrn.o \
X	top.o \
X	src.o \
X	patch.o \
X	patchtmp.o \
X	timbre.o \
X	system.o \
X	setuptmp.o \
X	keys.o
X
Xmt32.tos: $(OBJS)
X	cc -o mt32.tos $(OBJS) -lar
X
Xcp:
X	cp $(SRC) a:\src\mt32
SHAR_EOF
chmod 0444 makefile || echo "restore of makefile fails"
echo "x - extracting mt32.doc (Text)"
sed 's/^X//' << 'SHAR_EOF' > mt32.doc &&
XDoc for MT32 patch editor:
X
XThe program is full screen, the editing keys are:
X
Xnumeric fields:
X	F1  -16
X	F2  -8
X	F3  -4
X	F4  -2
X	F5  -1
X	F6  +1
X	F7  +2
X	F8  +4
X	F9  +8
X	F10 +10
X
XAlphanumeric fields:
X	There is no backspace (sorry about the bug)
X	a-z, A-Z, and 0-9 are permitted.
X
XMoving from field to field is accomplished with the four
Xarrow keys.
X
XTo exit the current screen hit escape.  To excecute the current
Xscreen and go to a sub-screen hit return.
X
XWhen the output is directed to the mt32 the
Xpatch editor will edit in live mode:  every change
Xwill be reflected immediately.  Messages from a keyboard
Xare copied from the ST's MIDI in and sent the MIDI out
Xwhich allows a keyboard to be used to play the synth
Xwhile making changes to the patch.  Be warned that the mt32
Xwill reject patch changes while sounding a tone.  So all
Xnotes on the synth keyboard should be off when making changes
Xon the ST's keyboard.
X
XWhen the output is directed to the mt32 the second and third
Xrow of keys (q-] and a-') on the ST's keyboard form all of the
Xnotes in the C arpeggio for all 8 octaves.  The space bar sends
Xan all notes off msg.  While more privitive than having a full keyboard,
Xit allows for live editing without a keyboard.
XThe keys 1 through 8 allow one to change velocity
Xsetting on the notes generated from thw ST's keyboard.
X
XCabling is difficult, there is no setup that lets you source
Xand sink to the mt32 and have a synth keyboard hooked up
Xall at the same time.  You get one or the other but not
Xboth.  To do live editing you need the MT-32's out connected
Xto the ST's in and the ST's out connected to the MT-32's in.
X
XFor synth keyboard usage, use the above cabling method first and
Xcopy the patches to disk files.  Then switch cables so that the
Xsynth kbd is connected to the ST's in.  The MT-32's out will
Xbe disconnected.  When done editing the new patch will be in the
Xmt-32's memory.  Another cable switch and you can copy the new patch
Xto a disk file.
X
XWhat all the patch fields are:
XAll of my names closely track Roland's names.
XThe mt32 and the D-50 have similar names for everything.
XI suggest a D-50 book if you can't find an mt32 book at
Xyour local music store.  The D-10/20/110 changed the names
Xfor everything, so while very similar, reading such doc
Xwill be confusing.
X
XAlso, I recommend reading the MIDI implementation in the back
Xfor sysex messages.  This is where I got my names and where you
Xcan find out which kind of memory does what.
X
XFile formats:
XMy file formats are exactly the sysex message it would take to
Xsend the data to the mt32.  Thus, if your sequencer allows importing
Xsuch files, you can store song setup information in your seqence.
XThe mt-32 needs about a half a second to digest each such message.
XI did not include a program that would dump sysex files to the
XMIDI port.  Such a program is trivial (for programmers) and I might
Xdo it for those interested.
X
X			- kurt
X
XOn compiling the source:
X	the memcpy.s file is not referenced in the makefile.
X	It is the only item needed from the archive libar.a
X	(-lar).
SHAR_EOF
chmod 0444 mt32.doc || echo "restore of mt32.doc fails"
exit 0