[comp.sources.atari.st] v01i090: d110edit -- Patch editor for D110 synthesizer

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

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

#!/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
#	  setuptmp.c
#	  src.c
#	  stdio.h
#	  system.c
#	  timbre.c
#	  timbretm.c
#	  tone.c
#	  top.c
#	  makefile
#	  d110.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 0664 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 0664 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 0664 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 0664 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 0664 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 0664 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_TIMBRE	0	/* timbre */
X#define T_TIMBRETMP	1	/* timbre tmp */
X#define T_TONE		2	/* tone memory */
X#define T_TONETMP	3	/* tone tmp memory */
X#define T_SYSTEM	4	/* system memory area */
X#define T_SETUPTMP	5	/* setup tmp area */
X#define T_PATCH		6	/* patch memory */
SHAR_EOF
chmod 0664 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 0664 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();
Xextern uchar mtwork[];
X
Xdata_t patchdata[] = {
X	{  1, 28, "D110 Patch Area" },
X	{  3, 10, "Patch Name   [          ]    Rhythm Output Volume 0-100  [   ]" },
X	{  5, 20, "parameters to edit part 1-8 (0 for none) [ ]" },
X	{  7,  1, "Reverb Mode Room 0-1, Hall 2-3, Plate 4, Tap delay 5-7, off 8  [ ]  (0-8)" },
X	{  9,  8, "Reverb Time  [ ]  1-8" },
X	{  9, 34, "Reverb Level  [ ]  0-7" },
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 patchfields[] = {
X/* y    x  type  len  max  offset  disp */
X{  3,  24,    1,  10,   0,      0,    0 },	/* patch name */
X{  3,  68,    0,   3, 100,      0,  127 },	/* rhythm output volume */
X{  5,  62,    0,   1,   8,      0,  128 },	/* parameter to edit */
X{  7,  65,    0,   1,   8,      0,   10 },      /* reverb mode */
X{  9,  22,    0,   1,   7,      1,   11 },      /* reverb time */
X{  9,  49,    0,   1,   7,      0,   12 },	/* reverb level */
X{  13,  6,    0,   2,  32,      0,   13 },	/* reserve ch 1 */
X{  13, 16,    0,   2,  32,      0,   14 },	/* reserve ch 2 */
X{  13, 26,    0,   2,  32,      0,   15 },	/* reserve ch 3 */
X{  13, 36,    0,   2,  32,      0,   16 },	/* reserve ch 4 */
X{  13, 46,    0,   2,  32,      0,   17 },	/* reserve ch 5 */
X{  13, 56,    0,   2,  32,      0,   18 },	/* reserve ch 6 */
X{  13, 66,    0,   2,  32,      0,   19 },	/* reserve ch 7 */
X{  13, 76,    0,   2,  32,      0,   20 },	/* reserve ch 8 */
X{  14,  8,    0,   2,  32,      0,   21 },	/* reserve rhythm */
X{  17,  6,    0,   2,  16,      1,   22 },      /* midi channel 1 */
X{  17, 16,    0,   2,  16,      1,   23 },      /* midi channel 2 */
X{  17, 26,    0,   2,  16,      1,   24 },      /* midi channel 3 */
X{  17, 36,    0,   2,  16,      1,   25 },      /* midi channel 4 */
X{  17, 46,    0,   2,  16,      1,   26 },      /* midi channel 5 */
X{  17, 56,    0,   2,  16,      1,   27 },      /* midi channel 6 */
X{  17, 66,    0,   2,  16,      1,   28 },      /* midi channel 6 */
X{  17, 76,    0,   2,  16,      1,   29 },      /* midi channel 7 */
X{  18,  8,    0,   2,  16,      1,   30 }       /* midi channel R */
X};
X
Xscreen_t patchscreen = {
X	patchdata,
X	sizeof(patchdata)/sizeof(data_t),
X	patchfields,
X	sizeof(patchfields)/sizeof(field_t),
X	mtgetdata,
X	mtputdata,
X	mtkeys,
X	mtdone
X};
X
Xdata_t paramdata[] = {
X{  1, 30, "D110 Patch Parameter Area" },
X{  4, 5, "Tone Group (a, b, i/c, r)                        [ ]   (0-3)" },
X{  5, 5, "Tone Number                                      [  ]  (0-63)" },
X{  6, 5, "Key Shift                                        [   ] (-24-24)" },
X{  7, 5, "Fine Tune                                        [   ] (-50-50)" },
X{  8, 5, "Bender Range                                     [  ]  (0-24)" },
X{  9, 5, "Assign Mode (single-last,s-first,multi-last,m-f) [ ]   (0-3)" },
X{ 10, 5, "Output Assign (-1 mix, 0 mix+reverb, 1-6         [  ]  (-1-6)" },
X{ 11, 5, "Output Level                                     [   ] (0-100)" },
X{ 12, 5, "Panpot                                           [  ]  (-7-7)" },
X{ 13, 5, "Key range Lower                                  [   ] (0-127)" },
X{ 14, 5, "Key range Upper                                  [   ] (0-127)" }
X};
X
Xfield_t paramfield[] = {
X/*   y   x   type   len   max   offset   disp */
X{    4, 55,     0,   1,     3,       0,     0 },	/* tone name */
X{    5, 55,     0,   2,    63,       0,     1 },	/* tone number */
X{    6, 55,     0,   3,    48,     -24,     2 },	/* key shift */
X{    7, 55,     0,   3,   100,     -50,     3 },	/* fine tune */
X{    8, 55,     0,   2,    24,       0,     4 },	/* bender range */
X{    9, 55,     0,   1,     3,       0,     5 },	/* assign mode */
X{   10, 55,     0,   2,     8,      -1,     6 },	/* output assign */
X{   11, 55,     0,   3,   100,       0,     8 },	/* output level */
X{   12, 55,     0,   2,    14,      -7,     9 },	/* panpot */
X{   13, 55,     0,   3,   127,       0,    10 },	/* key range lower */
X{   14, 55,     0,   3,   127,       0,    11 }		/* key range upper */
X};
X
X#define PDATASIZ	(sizeof(paramdata))
X#define PDATAS		(PDATASIZ/sizeof(data_t))
X#define PFIELDSIZ	(sizeof(paramfield))
X#define PFIELDS		(PFIELDSIZ/sizeof(field_t))
X#define PSCREENSIZ	(sizeof(paramscreen))
X
Xdata_t pdtmp[PDATAS];
Xfield_t pftmp[PFIELDS];
Xscreen_t pstmp;
X
Xscreen_t paramscreen = {
X	paramdata,
X	sizeof(paramdata)/sizeof(data_t),
X	paramfield,
X	sizeof(paramfield)/sizeof(field_t),
X	mtgetdata,
X	mtputdata,
X	mtkeys,
X	mtdone
X};
X
Xspatch()
X{
X	int s;
X	register field_t *fp;
X
X	mtwork[128] = 0;		/* param channel to edit */
X
X	for (;;) {
X		if (screen(&patchscreen) < 0)
X			return;
X		switch (s = mtwork[128]) {
X		case 0:			/* no partial edits */
X			return;
X		case 1:
X		case 2:
X		case 3:
X		case 4:
X		case 5:
X		case 6:
X		case 7:
X		case 8:
X			s--;
X			s *= 0x0c;		/* param data area */
X			s += 0x1f;		/* common data size */
X			memcpy(paramdata, pdtmp, PDATASIZ);
X			memcpy(paramfield, pftmp, PFIELDSIZ);
X			memcpy(&paramscreen, &pstmp, PSCREENSIZ);
X			pstmp.s_dp = pdtmp;
X			pstmp.s_fp = pftmp;
X			for (fp = pftmp; fp < &pftmp[PFIELDS]; fp++)
X				fp->f_disp += s;
X			screen(&pstmp);
X		}
X	}
X}
SHAR_EOF
chmod 0664 patch.c || echo "restore of patch.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, "D110 RHYTHM SETUP" },
X	{  3, 10, "Tone (1-64 memory, 65-127 Rhythm, 128 off)" },
X	{  3, 57, "[   ]" },
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, 58,     0,    3,  128,       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 0664 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_TIMBRE,       8,   8,  { 0x05, 0x00, 0x00 }, 128, "tmb" },
X	{ T_TIMBRETMP,   16,  16,  { 0x03, 0x00, 0x00 },   9, "tmt" },
X	{ T_TONE,       256, 246,  { 0x08, 0x00, 0x00 },  64, "tnm" },
X	{ T_TONETMP,    246, 246,  { 0x04, 0x00, 0x00 },   8, "tnt" },
X	{ T_SYSTEM,      33,  33,  { 0x10, 0x00, 0x00 },   1, "sys" },
X	{ T_SETUPTMP,     4,   4,  { 0x03, 0x01, 0x10 },  64, "set" },
X	{ T_PATCH,      128, 128,  { 0x06, 0x00, 0x00 },  64, "ptm" }
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 0664 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 0664 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, "Patch Name    [          ]" },
X{  7,  1, "Reverb Mode Room 0-1, Hall 2-3, Plate 4, Tap delay 5-7, off 8  [ ]  (0-8)" },
X	{  9,  8, "Reverb Time  [ ]  1-8" },
X	{  9, 34, "Reverb Level  [ ]  0-7" },
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,    1,  10,   0,      0,   23 },	/* patch name */
X{  7,  65,    0,   1,   8,      0,    1 },      /* reverb mode */
X{  9,  22,    0,   1,   7,      1,    2 },      /* reverb time */
X{  9,  49,    0,   1,   7,      0,    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 0664 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
Xuchar *mtgetdata();
Xint mtputdata();
Xint mtkeys();
Xint mtdone();
X
Xdata_t timbredata[] = {
X	{  1, 26, "D110 TIMBRE MEMORY" },
X	{  5,  8, "Tone Group (Group A, Group B, i/c Memory, Rhythm)" },
X	{  5, 58, "[ ]    (1-4)" },
X	{  7,  8, "Tone 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, "Output assign (-1 no reverb, 0 reverb, 1 thru 6" },
X	{ 17, 58, "[ ]    (-1-6)" }
X};
X
Xfield_t timbrefield[] = {
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,    7,      -1,     6 }		/* Output assign */
X};
X
Xscreen_t timbrescrn[] = {
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
Xstimbre()
X{
X	screen(timbrescrn);
X}
SHAR_EOF
chmod 0664 timbre.c || echo "restore of timbre.c fails"
echo "x - extracting timbretm.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > timbretm.c &&
X#include "mt.h"
X#include "mtscrn.h"
X
Xuchar *mtgetdata();
Xint mtputdata();
Xint mtkeys();
Xint mtdone();
X
Xdata_t timbretdata[] = {
X	{  1, 26, "D110 TIMBRE TMP MEMORY" },
X	{  5,  8, "Tone Group (Group A, Group B, Memory, Rhythm)" },
X	{  5, 58, "[ ]    (1-4)" },
X	{  7,  8, "Tone 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, "Output assign (-1 no reverb, 0 reverb, 1 thru 6)" },
X	{ 17, 58, "[ ]    (-1-6)" },
X	{ 19,  8, "Output level" },
X	{ 19, 58, "[   ]  (0-100)" },
X	{ 21,  8, "Panpot (Right to Left)" },
X	{ 21, 58, "[   ]  (-7 to 7)" },
X	{ 23,  8, "[   ]  lower kbd range" },
X	{ 23, 40, "[   ]  upper kbd range" }
X};
X
Xfield_t timbretfield[] = {
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,    7,      -1,     6 },		/* Output assign */
X{  19, 59,     0,    3,  100,       0,     8 },		/* output level */
X{  21, 59,     0,    2,   14,      -7,     9 },		/* panpot */
X{  23,  9,     0,    3,  127,       0,    10 },		/* lower kbd */
X{  23, 41,     0,    3,  127,       0,    11 }		/* upper kbd */
X};
X
Xscreen_t timbretscrn[] = {
X	timbretdata,
X	sizeof(timbretdata)/sizeof(data_t),
X	timbretfield,
X	sizeof(timbretfield)/sizeof(field_t),
X	mtgetdata,
X	mtputdata,
X	mtkeys,
X	mtdone
X};
X
Xstimbretmp()
X{
X	screen(timbretscrn);
X}
SHAR_EOF
chmod 0664 timbretm.c || echo "restore of timbretm.c fails"
echo "x - extracting tone.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > tone.c &&
X#include "mt.h"
X#include "mtscrn.h"
X
X#define TDATASIZ	(sizeof(tonedata))
X#define TDATAS		(TDATASIZ/sizeof(data_t))
X#define TFIELDSIZ	(sizeof(tonefield))
X#define TFIELDS		(TFIELDSIZ/sizeof(field_t))
X#define TSCREENSIZ	(sizeof(tonescreen))
X
Xuchar *mtgetdata();
Xint mtputdata();
Xint mtkeys();
Xint mtdone();
X
Xextern uchar mtwork[];
X
Xdata_t tonedata[] = {
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 tonefield[] = {
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 tonescreen = {
X	tonedata,
X	sizeof(tonedata)/sizeof(data_t),
X	tonefield,
X	sizeof(tonefield)/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, "D110 Tone 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
Xstone()
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(tonedata, tdtmp, TDATASIZ);
X			memcpy(tonefield, tftmp, TFIELDSIZ);
X			memcpy(&tonescreen, &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 0664 tone.c || echo "restore of tone.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, "D110 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 - D110 Memory" },
X	{ 12, 12, "Edit Type  [ ]    1 - Timbre     (*.tmb)" },
X	{ 13, 30, "2 - Timbre Tmp (*.tmt)" },
X	{ 14, 30, "3 - Tone       (*.tnm)" },
X	{ 15, 30, "4 - Tone Tmp   (*.tnt)" },
X	{ 16, 30, "5 - System     (*.sys)" },
X	{ 17, 30, "6 - Setup Tmp  (*.set)" },
X	{ 18, 30, "7 - Patch      (*.ptm)" },
X	{ 19, 30, "8 - 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 = 7;
X	for (;;) {
X		if (screen(&topscrn) < 0)
X			break;
X		if (edittype == 7)
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_TIMBRE:			/* timbre */
X			stimbre();
X			break;
X		case T_TIMBRETMP:		/* timbre tmp */
X			stimbretmp();
X			break;
X		case T_TONE:			/* tone */
X		case T_TONETMP:			/* tone tmp */
X			stone();
X			break;
X		case T_SYSTEM:			/* system */
X			ssystem();
X			break;
X		case T_SETUPTMP:		/* setup tmp */
X			ssetuptmp();
X			break;
X		case T_PATCH:			/* patch memory */
X			spatch();
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 0664 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	timbrre.c \
X	timbretm.c \
X	tone.c \
X	system.c \
X	setuptmp.c \
X	mttype.h \
X	keys.c \
X	patch.c
X
XOBJS =	mt.o \
X	mtscrn.o \
X	top.o \
X	src.o \
X	timbre.o \
X	timbretm.o \
X	tone.o \
X	system.o \
X	setuptmp.o \
X	keys.o \
X	patch.o
X
Xd110.tos: $(OBJS)
X	cc -o d110.tos $(OBJS) -lar
X
Xcp:
X	cp $(SRC) a:\src\d110
SHAR_EOF
chmod 0664 makefile || echo "restore of makefile fails"
echo "x - extracting d110.doc (Text)"
sed 's/^X//' << 'SHAR_EOF' > d110.doc &&
XDoc for d110 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
XNext and previous fields are the up and down arrow keys.
XLeft and right arrow keys allow moving around inside
Xan alphanumeric field.
X
XWhen the output is directed to the d110 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 d110
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 d110 the alphabetic keys on
Xthe ST's keyboard form all of the notes in the C arpeggio for
Xall 8 octaves.  The space bar sends an all notes off msg.
XWhile more privitive than having a full keyboard,
Xit allows for live editing without a keyboard.
X
XCabling is difficult, there is no setup that lets you source
Xand sink to the D110 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 D110's out connected
Xto the ST's in and the ST's out connected to the D110'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 D110's out will
Xbe disconnected.  When done editing the new patch will be in the
XD110'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.
XIf you have doubts, check the MIDI implementation reference
Xin the back since that is where my names came from.
X
XFile formats:
XMy file formats are exactly the sysex message it would take to
Xsend the data to the d110.  Thus, if your sequencer allows importing
Xsuch files, you can store song setup information in your seqence.
XThe d110 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 0664 d110.doc || echo "restore of d110.doc fails"
exit 0