/*
 * GLIB - a Generic LIBrarian and editor for synths
 *
 * DX-7 routines
 *
 * Scott Snyder - ssnyder@citromeo.bitnet, ssnyder@romeo.caltech.edu
 */

#define VCED_SIZE 155

#include "glib.h"
#include <ctype.h>
#include <math.h>

char *visnum(), *visonoff(), *vism3num(), *viswave(), *vismono();
char *visfreq(), *visdx1a(), *visr2num();

char *visdx7fq(), *visdx7fx(), *vism7num(), *visdx7note(), *visdx7crv();
char *visdx7a(), *visdx7wave(), *visdx7brkpt();

char *visdx7fq1(), *visdx7fq2(), *visdx7fq3();
char *visdx7fq4(), *visdx7fq5(), *visdx7fq6();
char *visdx7fx1(), *visdx7fx2(), *visdx7fx3();
char *visdx7fx4(), *visdx7fx5(), *visdx7fx6();

#define RESERVESIZE 0

/* This array contains arbitrary screen labels */
struct labelinfo Ldx7[] = {
#MENU
                      N: set name; q: quit; K: incr; J: decr; >: max; <: min  k
                      space: play autonote Pitch  %   Vol   %                h l
                                           Dur    %   Chan  %                 j

    Atk  Sust1 Sust2  Rls        Fix/  Out De  Rat  Sens   Brk  Depth  Curve   
OP Rt Lv Rt Lv Rt Lv Rt Lv  Freq Ratio Lvl tun Scl Key Mod Pt   L  R   L    R  
-- -- -- -- -- -- -- -- -- ----- ----- --- --- --- --- --- ---- -- -- ---- ----
 1 %  %  %  %  %  %  %  %  %     %      %   %   %   %   %  %    %  %  %    %   
 2 %  %  %  %  %  %  %  %  %     %      %   %   %   %   %  %    %  %  %    %   
 3 %  %  %  %  %  %  %  %  %     %      %   %   %   %   %  %    %  %  %    %   
 4 %  %  %  %  %  %  %  %  %     %      %   %   %   %   %  %    %  %  %    %   
 5 %  %  %  %  %  %  %  %  %     %      %   %   %   %   %  %    %  %  %    %   
 6 %  %  %  %  %  %  %  %  %     %      %   %   %   %   %  %    %  %  %    %   
PE %  %  %  %  %  %  %  %

Algorithm   %                    LFO Speed    %        Osc. Sync          @
==============                   LFO Delay    %        Feedback           @
                                 LFO AM Depth %        Middle C           @
                                 LFO PM Depth %
                                 LFO Wave     %
                                 LFO Sync     %
                                 LFO PM Sense %




#END
-1,-1,NULL
};

/* This array defines all the editable parameters. */
struct paraminfo Pdx7[] = {
"autopitch",	NULL, -1, -1, %%, visnum, 0, 127, 60, 0,
"autovol",	NULL, -1, -1, %%, visnum, 0, 127, 63, 0,
"autodur",	NULL, -1, -1, %%, visnum, 1,  20,  5, 0,
"autochan",	NULL, -1, -1, %%, visnum, 1,  16,  1, 0,

/*NAME		TYPE		POS	MAX	OFFSET	MASK	SHIFT	ADHOC*/
#O op1atkrt	r2num		%%	99	85
#O op1atklv	r2num		%%	99	89
#O op1sust1rt	r2num		%%	99	86
#O op1sust1lv	r2num		%%	99	90
#O op1sust2rt	r2num		%%	99	87
#O op1sust2lv	r2num		%%	99	91
#O op1rlsrt	r2num		%%	99	88
#O op1rlslv	r2num		%%	99	92
#O op1freq	dx7fq1		%%	4067	101			*3
#O op1coarsefq	num		--	255	100	0x3E	1	*4
#O op1fx	dx7fx1		%%	1	100	0x01
#O op1outlevel	num		%%	99	99
#O op1detune	m7num		%%	14	97	0x78	3
#O op1ratscl	num		%%	7	97	0x07
#O op1tchsens	num		%%	7	98	0x1C	2
#O op1modsens	num		%%	3	98	0x03
#O op1brkpt	dx7brkpt	%%	99	93
#O op1ldepth	r2num		%%	99	94
#O op1rdepth	r2num		%%	99	95
#O op1lcurve	dx7crv		%%	3	96	0x03
#O op1rcurve	dx7crv		%%	3	96	0x0C	2

#O op2atkrt	r2num		%%	99	68
#O op2atklv	r2num		%%	99	72
#O op2sust1rt	r2num		%%	99	69
#O op2sust1lv	r2num		%%	99	73
#O op2sust2rt	r2num		%%	99	70
#O op2sust2lv	r2num		%%	99	74
#O op2rlsrt	r2num		%%	99	71
#O op2rlslv	r2num		%%	99	75
#O op2freq	dx7fq2		%%	4067	84			*3
#O op2coarsefq	num		--	255	83	0x3E	1	*4
#O op2fx	dx7fx2		%%	1	83	0x01
#O op2outlevel	num		%%	99	82
#O op2detune	m7num		%%	14	80	0x78	3
#O op2ratscl	num		%%	7	80	0x07
#O op2tchsens	num		%%	7	81	0x1C	2
#O op2modsens	num		%%	3	81	0x03
#O op2brkpt	dx7brkpt	%%	99	76
#O op2ldepth	r2num		%%	99	77
#O op2rdepth	r2num		%%	99	78
#O op2lcurve	dx7crv		%%	3	79	0x03
#O op2rcurve	dx7crv		%%	3	79	0x0C	2

#O op3atkrt	r2num		%%	99	51
#O op3atklv	r2num		%%	99	55
#O op3sust1rt	r2num		%%	99	52
#O op3sust1lv	r2num		%%	99	56
#O op3sust2rt	r2num		%%	99	53
#O op3sust2lv	r2num		%%	99	57
#O op3rlsrt	r2num		%%	99	54
#O op3rlslv	r2num		%%	99	58
#O op3freq	dx7fq3		%%	4067	67			*3
#O op3coarsefq	num		--	255	66	0x3E	1	*4
#O op3fx	dx7fx3		%%	1	66	0x01
#O op3outlevel	num		%%	99	65
#O op3detune	m7num		%%	14	63	0x78	3
#O op3ratscl	num		%%	7	63	0x07
#O op3tchsens	num		%%	7	64	0x1C	2
#O op3modsens	num		%%	3	64	0x03
#O op3brkpt	dx7brkpt	%%	99	59
#O op3ldepth	r2num		%%	99	60
#O op3rdepth	r2num		%%	99	61
#O op3lcurve	dx7crv		%%	3	62	0x03
#O op3rcurve	dx7crv		%%	3	62	0x0C	2

#O op4atkrt	r2num		%%	99	34
#O op4atklv	r2num		%%	99	38
#O op4sust1rt	r2num		%%	99	35
#O op4sust1lv	r2num		%%	99	39
#O op4sust2rt	r2num		%%	99	36
#O op4sust2lv	r2num		%%	99	40
#O op4rlsrt	r2num		%%	99	37
#O op4rlslv	r2num		%%	99	41
#O op4freq	dx7fq4		%%	4067	50			*3
#O op4coarsefq	num		--	255	49	0x3E	1	*4
#O op4fx	dx7fx4		%%	1	49	0x01
#O op4outlevel	num		%%	99	48
#O op4detune	m7num		%%	14	46	0x78	3
#O op4ratscl	num		%%	7	46	0x07
#O op4tchsens	num		%%	7	47	0x1C	2
#O op4modsens	num		%%	3	47	0x03
#O op4brkpt	dx7brkpt	%%	99	42
#O op4ldepth	r2num		%%	99	43
#O op4rdepth	r2num		%%	99	44
#O op4lcurve	dx7crv		%%	3	45	0x03
#O op4rcurve	dx7crv		%%	3	45	0x0C	2

#O op5atkrt	r2num		%%	99	17
#O op5atklv	r2num		%%	99	21
#O op5sust1rt	r2num		%%	99	18
#O op5sust1lv	r2num		%%	99	22
#O op5sust2rt	r2num		%%	99	19
#O op5sust2lv	r2num		%%	99	23
#O op5rlsrt	r2num		%%	99	20
#O op5rlslv	r2num		%%	99	24
#O op5freq	dx7fq5		%%	4067	33			*3
#O op5coarsefq	num		--	255	32	0x3E	1	*4
#O op5fx	dx7fx5		%%	1	32	0x01
#O op5outlevel	num		%%	99	31
#O op5detune	m7num		%%	14	29	0x78	3
#O op5ratscl	num		%%	7	29	0x07
#O op5tchsens	num		%%	7	30	0x1C	2
#O op5modsens	num		%%	3	30	0x03
#O op5brkpt	dx7brkpt	%%	99	25
#O op5ldepth	r2num		%%	99	26
#O op5rdepth	r2num		%%	99	27
#O op5lcurve	dx7crv		%%	3	28	0x03
#O op5rcurve	dx7crv		%%	3	28	0x0C	2

#O op6atkrt	r2num		%%	99	0
#O op6atklv	r2num		%%	99	4
#O op6sust1rt	r2num		%%	99	1
#O op6sust1lv	r2num		%%	99	5
#O op6sust2rt	r2num		%%	99	2
#O op6sust2lv	r2num		%%	99	6
#O op6rlsrt	r2num		%%	99	3
#O op6rlslv	r2num		%%	99	7
#O op6freq	dx7fq6		%%	4067	16			*3
#O op6coarsefq	num		--	255	15	0x3E	1	*4
#O op6fx	dx7fx6		%%	1	15	0x01
#O op6outlevel	num		%%	99	14
#O op6detune	m7num		%%	14	12	0x78	3
#O op6ratscl	num		%%	7	12	0x07
#O op6tchsens	num		%%	7	13	0x1C	2
#O op6modsens	num		%%	3	13	0x03
#O op6brkpt	dx7brkpt	%%	99	8
#O op6ldepth	r2num		%%	99	9
#O op6rdepth	r2num		%%	99	10
#O op6lcurve	dx7crv		%%	3	11	0x03
#O op6rcurve	dx7crv		%%	3	11	0x0C	2

#O pegatkrt	r2num		%%	99	102
#O pegatklv	r2num		%%	99	106
#O pegsust1rt	r2num		%%	99	103
#O pegsust1lv	r2num		%%	99	107
#O pegsust2rt	r2num		%%	99	104
#O pegsust2lv	r2num		%%	99	108
#O pegrlsrt	r2num		%%	99	105
#O pegrlslv	r2num		%%	99	109

#O algorithm	dx7a		%%	31	110	0x1F

#O lfospeed	num		%%	99	112
#O lfodelay	num		%%	99	113
#O lfoamdepth	num		%%	99	115
#O lfopmdepth	num		%%	99	114
#O lfowave	dx7wave		%%	5	116	0x0E	1
#O lfosync	onoff		%%	1	116	0x01
#O lfopmsens	num		%%	7	116	0x70	4

#O oscsync	onoff		@@	1	111	0x08	3
#O feedback	num		@@	7	111	0x07
#O transpose	dx7note		@@	48	117

NULL,	NULL, -1, -1, -1, -1, visnum, 0, 0, 0, 0
};

#ifdef __TURBOC__
# pragma warn -par
#endif

#if !defined(TX81Z) && !defined(TX81ZPERF) && !defined(DX100)

/* else these routines are in yama_com */

setopval(n,str,v)
char *str;
{
	char buff[32];
	sprintf(buff,"op%d%s",n,str);
	setval(buff,v);
}

getopval(n,str)
char *str;
{
	char buff[32];
	sprintf(buff,"op%d%s",n,str);
	return(getval(buff));
}

char *
vismono(v)
{
	if ( v==0 )
		return("poly");
	else
		return("mono");
}

#endif

char *vism7num(v)
int v;
{
  static char Nbuff[16];

  sprintf(Nbuff, "%d", v-7);
  return Nbuff;
}

/* 2-digit, right-justified */
char *visr2num(v)
int v;
{
  static char Nbuff[16];

  sprintf(Nbuff, "%2d", v);
  return Nbuff;
}

char *Dx7Notes[] =
 { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };

char *visdx7note(v)
int v;
{
  int oct, tone;
  char *p;
  static char buf[8];

  oct = floor((double)v / 12.0);
  tone = v - oct*12;

  strcpy(buf, Dx7Notes[tone]);
  p = buf + (buf[1] == 0 ? 1 : 2);
  sprintf(p, "%d", oct+1);

  return buf;
}

char *visdx7brkpt(v)
int v;
{
  return visdx7note(v - 15);
}

char *visdx7crv(v)
int v;
{
  switch (v) {
    case 0: return "-LIN";
    case 1: return "-EXP";
    case 2: return "+EXP";
    case 3: return "+LIN";
    default: return "???";
  }
}

char *visdx7wave(v)
int v;
{
  switch (v) {
    case 0: return "Tri";
    case 1: return "Saw Down";
    case 2: return "Saw Up";
    case 3: return "Square";
    case 4: return "Sine";
    case 5: return "S/Hold";
    default: return "???";
  }
}

char *visdx7fqr(c, f)
int c, f;
{
  static char buf[8];
  float freq;

  freq = c;
  if (c == 0) freq = 0.5;

  freq += f * freq / 100;

  sprintf(buf, "%5.2f", freq);
  return buf;
}

int Dx7Freqs[] = {
  1000, 1023, 1047, 1072, 1096, 1122, 1148, 1175, 1202, 1230,
  1259, 1288, 1318, 1349, 1380, 1413, 1445, 1479, 1514, 1549,
  1585, 1622, 1660, 1698, 1738, 1778, 1820, 1862, 1905, 1950,
  1995, 2042, 2089, 2138, 2188, 2239, 2291, 2344, 2399, 2455,
  2512, 2570, 2630, 2692, 2716, 2818, 2884, 2951, 3020, 3090,
  3162, 3236, 3311, 3388, 3467, 3548, 3631, 3715, 3802, 3890,
  3981, 4074, 4169, 4266, 4365, 4467, 4571, 4677, 4786, 4898,
  5012, 5129, 5248, 5370, 5495, 5623, 5754, 5888, 6026, 6166,
  6310, 6457, 6607, 6761, 6918, 7079, 7244, 7413, 7586, 7762,
  7943, 8128, 8318, 8511, 8718, 8913, 9120, 9333, 9550, 9772,
};

char *visdx7fqf(c, f)
int c, f;
{
  static char buf[8];
  int i;

  c %= 4;

  sprintf(buf, "%4d ", Dx7Freqs[f]);

  if (c < 3) {
    for (i=4; i>c; i--)
      buf[i+1] = buf[i];
    buf[c+1] = '.';
  }

  return buf;
}

char *visdx7fq(v, op)
int v, op;
{
  char buff[8];
  int c, f;

  c = v / 128;
  f = v % 128;

  if (f > 99) {
    if (f > 110) {
      f = 99;
    }
    else {
      c++;
      f = 0;
    }
    setopval(op, "freq", c*128 + f);
  }

  sprintf(buff, "op%dfx", op);
  if (getval(buff) == 0)
    return visdx7fqr(c, f);
  else
    return visdx7fqf(c, f);
}

char *visdx7fx(v, op, s)   /* s == 1 for a DX7s */
int v, op, s;
{
  static int lastfx[] = { 0, -1, -1, -1, -1, -1, -1 };
  char buff2[8];
  int fqindex;

  if ( lastfx[op] != -1 && lastfx[op] == v )
    goto nochange;

  lastfx[op] = v;
  sprintf(buff2,"op%dfreq",op);
  fqindex = parmindex(buff2);
  showparam(fqindex,0);
nochange:
  if ( v == 0 )
    return(s ? " R" : "Ratio");
  else
    return(s ? "Hz" : "Fixed");
}

char *visdx7fx1(v) { return visdx7fx(v, 1, 0); }
char *visdx7fx2(v) { return visdx7fx(v, 2, 0); }
char *visdx7fx3(v) { return visdx7fx(v, 3, 0); }
char *visdx7fx4(v) { return visdx7fx(v, 4, 0); }
char *visdx7fx5(v) { return visdx7fx(v, 5, 0); }
char *visdx7fx6(v) { return visdx7fx(v, 6, 0); }

char *visdx7fq1(v) { return visdx7fq(v, 1); }
char *visdx7fq2(v) { return visdx7fq(v, 2); }
char *visdx7fq3(v) { return visdx7fq(v, 3); }
char *visdx7fq4(v) { return visdx7fq(v, 4); }
char *visdx7fq5(v) { return visdx7fq(v, 5); }
char *visdx7fq6(v) { return visdx7fq(v, 6); }

/*
  6+--5   6---5   3   6+   3   6+
  ++  |       |   |   ++   |   ||
  2   4   2+  4   2   5    2   5|   2   4   6+   2   4   6+
  |   |   ++  |   |   |    |   ||   |   |   ++   |   |   ||
  1   3   1   3   1   4    1   4|   1   3   5    1   3   5|
  +-+-+   +-+-+   +-+-+    +-+-++   +---+---+    +---+---++
    1       2       3        4          5            6

          6+           6           6           3+           3
          ++           |           |           ++           |
  2   4   5    2  +4   5   2+  4   5   5   6   2    5   6+  2
  |   |   |    |  ++   |   ++  |   |   |   |   |    |   ++  |
  1   3---+    1   3---+   1   3---+   +---4   1    +---4   1
  +-+-+        +-+-+       +-+-+           +-+-+        +-+-+
    7            8           9               10           11

                             5--+6+   5--+6      4  6+      4  6
  4  5  6  2+   4  5  6+ 2      |++      ||      |  ++      |  |
  |  |  |  ++   |  |  ++ |   2  +4    2+ +4   2  3  5    2+ 3  5
  +--3--+  1    +--3--+  1   |   |    ++  |   |  |  |    ++ |  |
     |     |       |     |   1   3    1   3   +--1--+    +--1--+
     +--+--+       +--+--+   +-+-+    +-+-+      |          |
        12            13       14       15       16         17

      6---5   3
          |   | 
  2   3+  4   2  +6       3+  5-+ 6   3+      6   2      6+
  |   ++  |   |  ++---+   ++--+ | |  ++++   +-++  |  +---++-+
  +---1---+   1   4   5   1   2 +-4  1  2   4  5  1  3   4  5
      |       +---+---+   +---+---+  +--+-+-+--+  +--+-+-+--+
      18          19          20          21           22

     3    6+         6+         6+      3   5  6+    3+  5  6+
     |   ++++      +-+++        +++     |   |  ++    ++  |  ++
  1  2   4  5  1 2 3 4 5  1 2 3 4 5  1  2   +--4  1  2   +--4
  +--+-+-+--+  +-+-+-+-+  +-+-+-+-+  +--+-+-+--+  +--+-+-+--+
       23          24         25          26           27

      5+                          5+
      ++                          ++
  2   4             4  6+         4             6+
  |   |             |  ++         |             ++
  1   3   6  1  2   3  5   1  2   3  6  1 2 3 4 5   1 2 3 4 5 6+
  +---+---+  +--+-+-+--+   +--+-+-+--+  +-+-+-+-+   +-+-+-+-+-++
      28          29            30          31            32
*/

char *Dx7Algstr[] = {
"1 ~3d~10l6~T~-~-5~n~[~]  ~|~n2   4~n~|   ~|~n1   3~n~[~-~T~-~]",
"2 ~3d~10l6~-~-~-5~n    ~|~n2~}  4~n~>~]  ~|~n1   3~n~[~-~T~-~]",
"3 ~3d~10l3   6~}~n~|   ~>~]~n2   5~n~|   ~|~n1   4~n~[~-~T~-~]",
"4 ~3d~10l3   6~}~n~|   ~|~|~n2   5~|~n~|   ~|~|~n1   4~|~n~[~-~T~-~^~]",
"5 ~5d~12l2   4   6~}~n~|   ~|   ~>~]~n1   3   5~n~[~3-~+~3-~]",
"6 ~5d~12l2   4   6~}~n~|   ~|   ~|~|~n1   3   5~|~n~[~3-~+~3-~^~]",
"7 ~3d~12l~8 6~}~n~8 ~>~]~n2   4   5~n~|   ~|   ~|~n1   3~3-~]~n~[~-~T~-~]",
"8 ~3d~12l~8 6~n~8 ~|~n2  ~{4   5~n~|  ~[~<   ~|~n1   3~3-~]~n~[~-~T~-~]",
"9 ~3d~12l~8 6~n~8 ~|~n2~}  4   5~n~>~]  ~|   ~|~n1   3~3-~]~n~[~-~T~-~]",
"10~3d~12l~8 3~}~n~8 ~>~]~n5   6   2~n~|   ~|   ~|~n~[~3-4   1~n~4 ~[~-~T~-~]",
"11~3d~12l~8 3~n~8 ~|~n5   6~}  2~n~|   ~>~]  ~|~n~[~3-4   1~n~4 ~[~-~T~-~]",
"12~4d~13l4  5  6  2~}~n~|  ~|  ~|  ~>~]~n~[~2-3~2-~]  1~n"
         "   ~|~5 ~|~n   ~[~2-~T~2-~]",
"13~4d~13l4  5  6~} 2~n~|  ~|  ~>~] ~|~n~[~2-3~2-~]  1~n"
         "   ~|~5 ~|~n   ~[~2-~T~2-~]",
"14~3d~10l5~2-~}6~}~n   ~|~>~]~n2  ~[4~n~|   ~|~n1   3~n~[~-~T~-~]",
"15~3d~10l5~2-~}6~n   ~|~|~n2~} ~[4~n~>~]  ~|~n1   3~n~[~-~T~-~]",
"16~3d~11l   4  6~}~n   ~|  ~>~]~n2  3  5~n~|  ~|  ~|~n~[~2-1~2-~]~n   ~|",
"17~3d~11l   4  6~n   ~|  ~|~n2~} 3  5~n~>~] ~|  ~|~n~[~2-1~2-~]~n   ~|",
"18~3d~12l~4 6~3-5~n~8 ~|~n2   3~}  4~n~|   ~>~]  ~|~n~[~3-1~3-~]~n~4 ~|",
"19~3d~12l3~n~|~n2  ~{6~n~|  ~[~+~3-~}~n1   4   5~n~[~3-~+~3-~]",
"20~5d~12l3~}  5~-~} 6~n~>~^~2-~} ~| ~|~n1   2 ~[~-4~n~[~3-~+~3-~]",
"21~5d~13l 3~}~6 6~n~{~^~^~}   ~{~-~^~}~n1  2   4  5~n~[~2-~^~-~T~-~^~2-~]",
"22~5d~13l2~6 6~}~n~|  ~{~3-~+~^~-~}~n1  3   4  5~n~[~2-~^~-~T~-~^~2-~]",
"23~5d~13l   3    6~}~n   ~|   ~{~^~^~}~n1  2   4  5~n~[~2-~^~-~T~-~^~2-~]",
"24~5d~13l~6 6~}~n    ~{~-~+~^~}~n1 2 3 4 5~n~[~-~^~-~+~-~^~-~]",
"25~5d~13l~6 6~}~n~6 ~>~^~}~n1 2 3 4 5~n~[~-~^~-~+~-~^~-~]",
"26~5d~13l   3   5  6~}~n   ~|   ~|  ~>~]~n1  2   ~[~2-4~n~[~2-~^~-~T~4-~]",
"27~5d~13l   3~}  5  6~}~n   ~>~]  ~|  ~>~]~n1  2   ~[~2-4~n~[~2-~^~-~T~4-~]",
"28~3d~12l~4 5~}~n~4 ~>~]~n2   4~n~|   ~|~n1   3   6~n~[~3-~+~3-~]",
"29~5d~13l~7 4  6~}~n~7 ~|  ~>~]~n1  2   3  5~n~[~2-~^~-~T~-~^~2-~]",
"30~3d~13l~7 5~}~n~7 ~>~]~n~7 4~n~7 ~|~n1  2   3  6~n~[~2-~^~-~T~-~^~2-~]",
"31~5d~12l~8 6~}~n~8 ~>~]~n1 2 3 4 5~n~[~-~^~-~+~-~^~-~]",
"32~7d~13l1 2 3 4 5 6~}~n~[~-~^~-~^~-~+~-~^~-~^~]",
};

char *visdx7a(v)
int v;
{
  if (v >= 0 && v < sizeof(Dx7Algstr)/sizeof(char *))
    return(Dx7Algstr[v]);
  else
    return("????");
}

dx7din(data)
char *data;
{
#SETVAL
}

dx7dout(data)
char *data;
{
#GETVAL

  Channel = getval("autochan");
}

char *dx7nof(data)
char *data;
{
  static char buf[11];
  char *p;
  int i;

  p = buf;
  for (i=118; i<=127; i++)
    *p++ = data[i];

  *p = '\0';

  return buf;
}

dx7snof(data, name)
char *data, *name;
{
  int i;

  for (i=118; i<=127 && *name; i++)
    data[i] = *name++;
  for (; i<=127; i++)
    data[i] = ' ';
}

dx7vmemtovced(in, out)
char *in, *out;
{
  int i;
  char *opin, *opout;

  for (i=0; i<6; i++) {
    opin = in + (6-i-1)*17;
    opout = out + (6-i-1)*21;

    opout[ 0] = opin[ 0];		/* eg rate 1 */
    opout[ 1] = opin[ 1];		/* eg rate 2 */
    opout[ 2] = opin[ 2];		/* eg rate 3 */
    opout[ 3] = opin[ 3];		/* eg rate 4 */
    opout[ 4] = opin[ 4];		/* eg level 1 */
    opout[ 5] = opin[ 5];		/* eg level 2 */
    opout[ 6] = opin[ 6];		/* eg level 3 */
    opout[ 7] = opin[ 7];		/* eg level 4 */
    opout[ 8] = opin[ 8];		/* breakpoint */
    opout[ 9] = opin[ 9];		/* l. depth */
    opout[10] = opin[10];		/* r. depth */
    opout[11] = opin[11] & 0x03;	/* l. curve */
    opout[12] = (opin[11]>>2) & 0x03;	/* r. curve */
    opout[13] = opin[12] & 0x07;	/* rate scaling */
    opout[14] = opin[13] & 0x03;	/* mod. sens. */
    opout[15] = (opin[13]>>2) & 0x07;	/* touch sens. */
    opout[16] = opin[14];		/* total level */
    opout[17] = opin[15] & 0x01;	/* freq. mode */
    opout[18] = (opin[15]>>1) & 0x1f;	/* coarse freq. */
    opout[19] = opin[16];		/* fine freq. */
    opout[20] = (opin[12]>>3) & 0x0f;	/* detune */
  }

  out[126] = in[102];			/* peg rate 1 */
  out[127] = in[103];			/* peg rate 2 */
  out[128] = in[104];			/* peg rate 3 */
  out[129] = in[105];			/* peg rate 4 */
  out[130] = in[106];			/* peg level 1 */
  out[131] = in[107];			/* peg level 2 */
  out[132] = in[108];			/* peg level 3 */
  out[133] = in[109];			/* peg level 4 */
  out[134] = in[110] & 0x1f;		/* algorithm */
  out[135] = in[111] & 0x07;		/* feedback */
  out[136] = (in[111]>>3) & 0x01;	/* osc sync */
  out[137] = in[112];			/* lfo speed */
  out[138] = in[113];			/* lfo delay time */
  out[139] = in[114];			/* pm depth */
  out[140] = in[115];			/* am depth */
  out[141] = in[116] & 0x01;		/* lfo key sync */
  out[142] = (in[116]>>1) & 0x07;	/* lfo wave */
  out[143] = (in[116]>>4) & 0x0f;	/* lfo pm sens */
  out[144] = in[117];			/* transpose */

  for (i=0; i<10; i++)
    out[145+i] = in[118+i];		/* name */
}

dx7send_bulk(format, length, data)
int format, length;
char *data;
{
  int csum, i;

  sendmidi(0xf0);
  sendmidi(0x43);
  sendmidi(Channel-1);
  sendmidi(format);
  sendmidi(length / 128);
  sendmidi(length % 128);

  csum = 0;
  for (i=0; i<length; i++) {
    sendmidi(data[i]);
    csum += data[i];
  }

  sendmidi((-csum) & 0x7f);
  sendmidi(EOX);

  return 0;
}

dx7svced(data)
char *data;
{
  return dx7send_bulk(0, VCED_SIZE, data);
}

dx7sedit(data)
char *data;
{
  char edmem[VCED_SIZE];

  dx7vmemtovced(data, edmem);
  return dx7svced(edmem);
}

dx7sbulk(data)
char *data;
{
  return dx7send_bulk(9, 4096, data);
}

dx7get_bulk(format, maxlength, data)
unsigned format, maxlength;
char *data;
{
  int c, n, b1, b2, cksum, ret = 1;
  unsigned len;
  long begin, toolong;
  static char ckbuff[80];

  flushmidi();

  begin = milliclock();
  toolong = begin + 1000 * TIMEOUT;

  sendmidi(0xf0);
  sendmidi(0x43);
  sendmidi(0x20 | (Channel-1) );	/* Channel # */
  sendmidi(format);			/* 4 == 32 voice bulk dump */
  sendmidi(EOX);			/* EOX */

#ifdef BYTEBOARD
# ifdef __TURBOC__
#  pragma warn -rch
# endif
  if (midi_getsex(toolong) == NULL) return 1;
#endif

  /* wait for the x43 byte starting the dump */
  c = 0;
  while ( milliclock() < toolong ) {
    if ( STATMIDI && (c=(getmidi() & 0xff)) == 0x43 )
      break;
  }
  if ( c != 0x43 ) {
    Reason = "Timeout waiting for 0x43";
    goto getout;
  }

  getmidi();		/* channel # */
  c = getmidi();	/* format # */
  if (c != format) {
    sprintf(ckbuff, "Synth sent format %d instead of %d", c, format);
    Reason = ckbuff;
    goto getout;
  }
  len = 128 * getmidi();	/* byte count high byte */
  len += getmidi();		/* byte count low byte */
  if (len > maxlength) {
    Reason = "Synth sent more data than I was expecting";
    goto getout;
  }

  cksum = 0;
  /* 32 voices are dumped */
  for (n=0; n<len; n++) {
    /* twiddle your thumbs, but not forever */
anotherch:
    while ( ! STATMIDI ) {
      if ( milliclock() > toolong )
        goto timeout;	/* the end of an era */
    }
    c = (getmidi() & 0xff);
    /* Ignore non-data bytes ? */
    if ( c & 0x80 )
      goto anotherch;
    /* compute checksum */
    cksum += c;
    data[n] = c;
  }
timeout:
  if ( n < len ) {
    Reason = "Timeout while reading!";
    goto getout;
  }
  b1 = (getmidi() & 0xff);	/* Checksum */
  b2 = (getmidi() & 0xff);	/* EOX */
  cksum = (-cksum) & 0x7f;	/* convert to what we must match */
  if ( b2 != EOX )
    Reason = "EOX not received";
  else if ( b1 != cksum ) {
    sprintf(ckbuff,"Checksum doesn't match (got %d expected %d)",b1,cksum);
    Reason = ckbuff;
  }
  else {
    Reason = "";
    ret = 0;	/* all's well */
  }
getout:
  return(ret);
}

dx7gbulk(data)
char *data;
{
  return dx7get_bulk(9, 4096, data);
}
