allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (05/15/89)
Posting-number: Volume 6, Issue 109 Submitted-by: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee ) Archive-name: glib/part08 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 8 (of 15)." # Contents: dep5.mnu mac-mdr.a tx81p.mnu # Wrapped by lee@uhccux on Sun May 7 00:40:15 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'dep5.mnu' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dep5.mnu'\" else echo shar: Extracting \"'dep5.mnu'\" \(18882 characters\) sed "s/^X//" >'dep5.mnu' <<'END_OF_FILE' X/* $Id: dep5.mnu,v 1.6 89/05/06 17:13:20 lee Exp $ X * GLIB - a Generic LIBrarian and editor for synths X * X * DEP-5 routines. X * Tim Thompson X * X * The DEP-5 is a mess, the code below is likewise. There are only 12 X * parameters or so, but there are 11 algorithms, and different parameters X * have different meanings and ranges in each algorithm. Also, the displayed X * values have NO regular relationship to the byte values of the parameters, X * hence the need for all the huge tables. X * X * modifications: Greg Lee X * $Log: dep5.mnu,v $ X * Revision 1.6 89/05/06 17:13:20 lee X * rel. to comp.sources.misc X * X * X */ X X#define OVERLAY2 X X#include "glib.h" X#include <ctype.h> X X#define DEP5VSIZE 42 X#define DEP5NSIZE 16 X#define DEP5NVOICES 99 X#define RESERVESIZE 0 X Xchar D5buff[16]; Xint Alg; /* current algorithm, 0-10 */ X Xchar *visnum(), *visonoff(), *vism3num(), *viswave(), *vismono(); Xchar *visd5alg(), *visdcr(), *visdcd(), *visdcf(), *visdrs(), *visd5pd(); Xchar *visd5rt(), *visd5hf(), *visd5no(), *visd5q(), *visd5fm(), *visd5bc(); X Xstruct numpair { X int np_byte; X int np_val; X}; X Xstruct hfpair { X short hf_byte; X short hf_val; X}; X X X#define NUMHF 96 X#define NUMCD 223 X#define NUMFREQ 128 X#define NUMGATE 256 X#define NUMCF 256 X#define NUMCR 97 X#define NUMNLRT 151 X#define NUMRT 153 X#define NUMDT 256 X#define NUMPD 256 Xstruct numpair *Revtime; Xstruct numpair *Nlrevtime; Xstruct hfpair *Hf; Xstruct numpair *Chdepth; Xstruct numpair *Chrate; Xint *Predly; Xint *Chfeed; Xint *Dtime; Xint *Freqmid; Xint *Gatetime; X X/* This array contains arbitrary screen labels */ Xstruct labelinfo Ldep5[] = { X#MENU X X X Algorithm % X =========== X X<Equalizer> <Chorus> X Output Level % Feedback of Chorus % X Boost/Cut of Low % Rate of Chorus % X Boost/Cut of Mid % Depth of Chorus % X Boost/Cut of High % <Reverb> X Q of Mid % Pre-Delay % X Freq (KHz) of Mid % Reverb Time % X HF Damping % X-------------------------+ Reverb Selection % XN - set name q - quit | <Non-Linear> Xh - left j - down | Xk - up l - right | XJ - decr K - incr | Xspace = play auto-note | X | <Delay> XAuto-Note: | X Pitch % Vol % | X Dur % Chan % | X | X#END X-1,-1,NULL X}; X Xstruct paraminfo Pdep5[] = { X/* XNAME TYPE POS MAX OFFSET MASK SHIFT ADHOC X */ X#O algorithm d5alg %% 10 0 X#O chorfeed dcf %% 255 0 X#O outlev num %% 99 1 X#O chorrate dcr %% 96 0 X#O lowfilt d5bc %% 24 0 X#O chordepth dcd %% 222 0 X#O midfilt d5bc %% 24 0 X#O highfilt d5bc %% 24 0 X#O predelay d5pd %% 255 0 X#O q d5q %% 90 2 X#O reverbtime d5rt %% 152 0 X#O freqmid d5fm %% 127 3 X#O hfdamp d5hf %% 95 0 X#O reverbsel drs %% 21 0 X#O autovol num %% 127 -63 X#O autopitch num %% 127 -60 X#O autochan num %% 16 -1 *5 X#O autodur num %% 20 -5 *5 XNULL,NULL,-1,-1,-1,-1,visnum,0,0,0,0 X}; X X X/* X * dep5din X * X * Take info from 'data' and stuff values in the P array, by using X * the setval functionms. X */ X Xdep5din(data) Xchar *data; X{ X initdp5(); X X Alg = d5algin(data[16] | ((data[17]&0xf)<<4)); X setval("algorithm", Alg); X X setval("reverbsel",data[0]); X setval("outlev",data[1]); X setval("q",data[2]); X setval("freqmid",data[3]); X /* these parameters take up 2 bytes (4bits in each) */ X setval("lowfilt", d5bcin(data[4] | ((data[5]&0xf)<<4)) ); X setval("midfilt", d5bcin(data[6] | ((data[7]&0xf)<<4)) ); X setval("highfilt", d5bcin(data[8] | ((data[9]&0xf)<<4)) ); X setval("chorfeed", data[10] | ((data[11]&0xf)<<4) ); X setval("chorrate",d5vin(Chrate,data[12] | ((data[13]&0xf)<<4))); X setval("chordepth",d5vin(Chdepth,data[14] | ((data[15]&0xf)<<4))); X setval("predelay", data[18] | ((data[19]&0xf)<<4) ); X setval("reverbtime", d5rtin(data[20] | ((data[21]&0xf)<<4)) ); X setval("hfdamp", d5hfin(data[22] | ((data[23]&0xf)<<4)) ); X X setval("autochan",Channel); X X} X X/* X * dep5dout X * X * Take (possibly changed) parameters values out of the P array and X * put them back into 'data'. X */ X Xdep5dout(data) Xchar *data; X{ X int n, alg; X X alg = d5algout(getval("algorithm")); X data[16] = alg & 0xf; X data[17] = (alg >> 4) & 0xf; X X data[0] = getval("reverbsel"); X data[1] = getval("outlev"); X data[2] = getval("q"); X data[3] = getval("freqmid"); X X /* these parameters take up 2 bytes (4bits in each) */ X n = d5bcout(getval("lowfilt")); X data[4] = n & 0xf; X data[5] = (n >> 4) & 0xf; X n = d5bcout(getval("midfilt")); X data[6] = n & 0xf; X data[7] = (n >> 4) & 0xf; X n = d5bcout(getval("highfilt")); X data[8] = n & 0xf; X data[9] = (n >> 4) & 0xf; X n = getval("chorfeed"); X data[10] = n & 0xf; X data[11] = (n >> 4) & 0xf; X n = d5crout(getval("chorrate")); X data[12] = n & 0xf; X data[13] = (n >> 4) & 0xf; X n = d5cdout(getval("chordepth")); X data[14] = n & 0xf; X data[15] = (n >> 4) & 0xf; X n = getval("predelay"); X data[18] = n & 0xf; X data[19] = (n >> 4) & 0xf; X n = d5rtout(getval("reverbtime")); X data[20] = n & 0xf; X data[21] = (n >> 4) & 0xf; X n = d5hfout(getval("hfdamp")); X data[22] = n & 0xf; X data[23] = (n >> 4) & 0xf; X X Channel = getval("autochan"); X} X X/* X * dep5sedit X * X * Send a single voice to the edit buffer of the dep5. X */ Xdep5sedit(data) Xchar *data; X{ X dep5parms(data); X} X Xdep5parms(data) Xchar *data; X{ X int n; X X sendmidi(0xf0); X sendmidi(0x41); /* Roland */ X sendmidi(0x35); /* operation code = APR (all parameters) */ X sendmidi(Channel-1); /* MIDI channel */ X sendmidi(0x52); /* format type */ X sendmidi(0x20); /* level # = 1 */ X sendmidi(0x01); /* group # = 1 */ X /* send 24 bytes of parameter info */ X for ( n=0; n<24; n++ ) { X sendmidi((int)(data[n])); X } X sendmidi(EOX); X} X X/* dep5nof - return a pointer to the voice name buried in data */ Xchar * Xdep5nof(data) Xchar *data; X{ X static char currbuff[DEP5NSIZE+1]; X char *p; X int m; X X p = currbuff; X for ( m=0; m<DEP5NSIZE; m++ ) X *p++ = data[24+m]; X *p = '\0'; X return(currbuff); X} X X/* setnameof - set the voice name buried in data to name */ Xdep5snof(data,name) Xchar *data; Xchar *name; X{ X char *p; X int m; X X for ( p=name,m=0; *p!='\0' && m<DEP5NSIZE; p++,m++ ) X data[24+m] = *p; X for ( ; m<DEP5NSIZE; m++ ) X data[24+m] = '\0'; X} X X/* dep5sone - send and store one voice */ Xdep5sone(voicenum,data) Xchar *data; X{ X /* Send the parameters for this voice. */ X dep5parms(data); X X /* now ask it to be stored into memory */ X sendmidi(0xf0); X sendmidi(0x41); /* Roland */ X sendmidi(0x34); /* operation code = PGR (program #) */ X sendmidi(Channel-1); /* MIDI channel */ X sendmidi(0x52); /* format type */ X sendmidi(0x20); /* level # = 1 */ X sendmidi(0x00); /* group # = 0 */ X sendmidi(0x00); /* extension = 0 */ X sendmidi(voicenum & 0x7f); /* memory number (minus 1) */ X sendmidi(0x02); /* writing data to memory */ X sendmidi(EOX); X X Reason = ""; X return(0); /* can't fail */ X} X Xchar *D5alg[] = { X"1 ---EQ---Chorus---<~u/----~d~d~l~l~l~l~l\\----", X"2 ---EQ---Reverb---<~u/----~d~d~l~l~l~l~l\\----", X"3 ---EQ---Reverb(Mod)---<~u/----~d~d~l~l~l~l~l\\----", X"4 ---EQ---Reverb(Mod)---Chorus---<~u/----~d~d~l~l~l~l~l\\----", X"5 ---EQ-+-Reverb--< +-Chorus---<~u/~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l\ X/~u/--------------+---~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~d~d~d~\ Xl~l~l~l~l~l~l~l~l|__________\\__|~l~l~l~d\\--------------~l~u\\~d+---", X"6 ---EQ---Reverb--<--Chorus---<~u/~l~l~l~l~l~l~l~l~l~l~l~l~l\ X/~u/-----------+---~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~d~d~d~\ Xl\\~d\\-----------~l~u\\~d+---", X"7 ---EQ---NLR---<~u/----~d~d~l~l~l~l~l\\----", X"8 ---EQ---NLR(Mod)---<~u/----~d~d~l~l~l~l~l\\----", X"9 ---EQ---NLR--<--Chorus---<~u/~l~l~l~l~l~l~l~l~l~l~l~l~l\ X/~u/-----------+---~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~d~d~d~\ Xl\\~d\\-----------~l~u\\~d+---", X"10 ---EQ---Delay--<--Chorus---<~u/~l~l~l~l~l~l~l~l~l~l~l~l~l\ X/~u/-----------+---~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~d~d~d~\ Xl\\~d\\-----------~l~u\\~d+---", X"11 ---EQ---NLR(Mod)---<~u/----~d~d~l~l~l~l~l\\----", X}; X X#define NPARM 12 Xchar Algparms[][NPARM] = { X1,1,1,0,0,0,0,1,1,1,1,1, /* alg 1 */ X0,0,0,1,1,1,1,1,1,1,1,1, /* alg 2 */ X0,1,1,1,1,1,1,1,1,1,1,1, /* alg 3 */ X1,1,1,1,1,1,1,1,1,1,1,1, /* alg 4 */ X1,1,1,1,1,1,1,1,1,1,1,1, /* alg 5 */ X1,1,1,1,1,1,1,1,1,1,1,1, /* alg 6 */ X0,0,0,1,1,1,1,1,1,1,1,1, /* alg 7 */ X0,1,1,1,1,1,1,1,1,1,1,1, /* alg 8 */ X1,1,1,1,1,1,1,1,1,1,1,1, /* alg 9 */ X1,1,1,1,1,1,1,1,1,1,1,1, /* alg 10 */ X0,1,1,1,1,1,1,1,1,1,1,1 /* alg 11 */ X}; X/* for the parameters in the array above, Algmap gives the index in P */ Xint Algmap[] = {1,2,3,4,5,6,7,8,9,10,11,12}; X X/* X * visd5alg X * X * Whenever the algorithm is changed, we have to change the X * meanings/locations/ranges of various parameters. X */ X Xchar * Xvisd5alg(v) X{ X static int rt = -1, pd, hf, rs; X int n; X X if ( rt == -1 ) { X pd = parmindex("predelay"); X hf = parmindex("hfdamp"); X rt = parmindex("reverbtime"); X rs = parmindex("reverbsel"); X } X if ( v >= 0 && v <= 10 ){ X Alg = v; X /* Enable the parameters that this algorithm uses */ X for ( n=0; n<NPARM; n++ ) { X if ( Algparms[v][n] == 1 ) X enableparm(Algmap[n]); X else X disableparm(Algmap[n]); X } X if ( v == 9 ) { X P[pd].p_vrow=P[pd].p_lrow=20; X P[pd].p_label = "Delay Time"; X X P[rt].p_vrow=P[rt].p_lrow=21; X P[rt].p_label = "Delay Feedback"; X P[rt].p_max = 255; X X P[hf].p_vrow=P[hf].p_lrow=22; X P[hf].p_label = "HF Damp"; X P[hf].p_max = 95; X X P[rs].p_vrow=P[rs].p_lrow=23; X P[rs].p_label = "Delay Output"; X P[rs].p_max = 2; X } X else if ( v<6 ) { X P[pd].p_vrow=P[pd].p_lrow=10; X P[pd].p_label = "Pre-Delay"; X X P[rt].p_vrow=P[rt].p_lrow=11; X P[rt].p_label = "Reverb Time"; X P[rt].p_max = 152; X X P[hf].p_vrow=P[hf].p_lrow=12; X P[hf].p_label = "HF Damp"; X P[hf].p_max = 95; X X P[rs].p_vrow=P[rs].p_lrow=13; X P[rs].p_label = "Reverb Selection"; X P[rs].p_max = 21; X } X else { X P[pd].p_vrow=P[pd].p_lrow=15; X P[pd].p_label = "NL Pre-Delay"; X X P[rt].p_vrow=P[rt].p_lrow=16; X P[rt].p_label = "NL Reverb Time"; X P[rt].p_max = 150; X X P[hf].p_vrow=P[hf].p_lrow=17; X P[hf].p_label = "NL Gate Time"; X P[hf].p_max = 255; X X P[rs].p_vrow=P[rs].p_lrow=18; X P[rs].p_label = "NL Output"; X P[rs].p_max = 2; X } X Redraw = 1; X return(D5alg[v]); X } X else X return("????"); X} X Xint Algval[] = { 0, 3, 31, 59, 87, 115, 143, 171, 199, 227, 255 }; X Xd5algin(d) X{ X int n = 0; X X while ( d >= Algval[n] && n <= 10 ) X n++; X return(n-1); X} X Xd5algout(v) X{ X return(Algval[v]); X} X Xd5vin(nparr,v) Xstruct numpair *nparr; X{ X int n; X X for ( n=0; nparr[n].np_val >= 0; n++ ) { X if ( v <= nparr[n].np_byte ) X return(n); X } X return(0); X} X Xchar * Xvisdcr(v) X{ X if ( v >= 0 && v< NUMCR ) { X v = Chrate[v].np_val; X sprintf(D5buff,"%d.%d",v/10,v%10); X return(D5buff); X } X else X return("??"); X} X Xd5crout(v) X{ X if ( v >= 0 && v< NUMCR ) X return(Chrate[v].np_byte); X else X return(0); X} X Xchar * Xvisdcd(v) X{ X if ( v >= 0 && v< NUMCD ) { X v = Chdepth[v].np_val; X sprintf(D5buff,"%d.%d",v/10,v%10); X return(D5buff); X } X else X return("??"); X} Xd5cdout(v) X{ X if ( v >= 0 && v< NUMCD ) X return(Chdepth[v].np_byte); X else X return(0); X} X X Xchar * Xvisdcf(v) X{ X if ( v >= 0 && v< 256 ) { X v = Chfeed[v]; X sprintf(D5buff,"%d.%d",v/10,v%10); X return(D5buff); X } X else X return("??"); X} X Xchar * Xvisd5no(v) X{ X char *p; X switch (v) { X case 0: p = "Normal"; break; X case 1: p = "Pan B to A"; break; X case 2: p = "Pan A to B"; break; X } X return(p); X} X Xchar * Xvisddo(v) X{ X char *p; X switch (v) { X case 0: p = "Normal"; break; X case 1: p = "Invert Phase"; break; X case 2: p = "Pan A to B"; break; X } X return(p); X} X Xchar *Revsel[] = { "Special 1", "Special 2", "Plate 1", "Plate 2", X "Hall 14'","Hall 20'","Hall 27'","Hall 36'","Hall 48'","Hall 61'","Hall 76'", X "Room 0.3'","Room 1.4'","Room 3.1'","Room 8.2'","Room 14'","Room 20'", X "Room 27'","Room 36'","Room 48'","Room 61'","Room 76'" X}; X Xchar * Xvisdrs(v) X{ X /* For algorithms 6,7,8,10, the reverb select parameter */ X /* is the NL output */ X if ( Alg==6 || Alg==7 || Alg==8 || Alg==10 ) X return(visd5no(v)); X if ( Alg == 9 ) X return(visddo(v)); X if ( v>=0 && v<22 ) { X rtclip(); X return(Revsel[v]); X } X return("??"); X} X Xchar * Xvisddt(v) X{ X int rem; X X if ( v < 0 || v >= NUMDT ) X return("??"); X v = Dtime[v]; X if ( v < 1000 ) X sprintf(D5buff,"%d",v); X else { X rem = (v%1000)/10; X sprintf(D5buff,(rem<10)?"%d.0%d":"%d.%d",v/1000,rem); X } X return(D5buff); X} X Xchar * Xvisd5pd(v) X{ X if ( v < 0 || v >= NUMPD ) X return("??"); X /* For algorithm 9 (aka 10), the predelay parameter is the delay time*/ X if ( Alg == 9 ) X return(visddt(v)); X else X sprintf(D5buff,"%d",(int)Predly[v]); X return(D5buff); X} X Xd5rtin(v) X{ X register int n; X X if ( Alg==9 ) X return(v); X else if ( Alg==6 || Alg==7 || Alg==8 || Alg==10 ) { X for ( n=0; n<NUMNLRT; n++ ) { X if ( v < Nlrevtime[n].np_byte ) X break; X } X return(n-1); X } X else { X for ( n=0; n<NUMRT; n++ ) { X if ( v < Revtime[n].np_byte ) X break; X } X return(n-1); X } X} X Xd5rtout(v) X{ X if ( Alg==9 ) X return(v); X else if ( Alg==6 || Alg==7 || Alg==8 || Alg==10 ) X return(Nlrevtime[v].np_byte); X else X return(Revtime[v].np_byte); X} X Xchar * Xvisd5rt(v) X{ X /* In algorithm 9 (aka 10), the reverb time parameter is */ X /* the delay feedback. */ X if ( Alg == 9 ) { X if ( v<0 || v>=NUMCF ) X return("??"); X else X return(visdcf(v)); X } X else if ( Alg==6 || Alg==7 || Alg==8 || Alg == 10 ) { X if ( v<0 || v>=NUMNLRT ) X return("??"); X v = Nlrevtime[v].np_val; X if ( v < 0 ) X sprintf(D5buff,"-0.%d",-v); X else if ( v < 10 ) X sprintf(D5buff,"0.%d",v); X else if ( v < 100 ) X sprintf(D5buff,"%d.%d",v/10,v%10); X else X sprintf(D5buff,"%d",v/10); X return(D5buff); X } X else if ( v >= 0 && v < NUMRT ) { X v = rtclip(); X v = Revtime[v].np_val; X if ( v < 100 ) X sprintf(D5buff,"%d.%d ",v/10,v%10); X else X sprintf(D5buff,"%d ",v/10); X return(D5buff); X } X else X return("?? "); X} X Xchar * Xvisd5gt(v) X{ X if ( v >=0 && v < NUMGATE ) { X sprintf(D5buff,"%d",Gatetime[v]); X return(D5buff); X } X else X return("??"); X} X X Xchar * Xvisd5hf(v) X{ X if ( Alg==6 || Alg==7 || Alg==8 || Alg==10 ) { X return(visd5gt(v)); X } X else if ( v >= 0 && v < NUMHF ) { X v = Hf[v].hf_val; X if ( v >= 10 ) X sprintf(D5buff,"%d.%d",v/100,v%100); X else X sprintf(D5buff,"0.0%d",v%100); X return(D5buff); X } X else X return("??"); X} X Xd5hfout(v) X{ X if ( Alg==6 || Alg==7 || Alg==8 || Alg==10 ) X return(v); X else X return(Hf[v].hf_byte); X} X Xd5hfin(d) X{ X register int n; X X if ( Alg==6 || Alg==7 || Alg==8 || Alg==10 ) X return(d); X for ( n=0; Hf[n].hf_byte >= 0 ; n++ ) { X if ( d < Hf[n].hf_byte ) X break; X } X return(n-1); X} X Xint Revmin[] = { 10,10,7,7,1,2,3,4,5,6,7,1,1,1,1,1,2,3,4,5,6,7 }; Xint Revmax[] = { 990,990,990,990,200,400,720,990,990,990,990, X 5,15,35,75,200,400,720,990,990,990,990 X}; X Xrtclip() X{ X int rtval, rtype, origrtval; X X origrtval = rtval = getval("reverbtime"); X rtype = getval("reverbsel"); X while ( Revtime[rtval].np_val < Revmin[rtype] ) X rtval++; X while ( Revtime[rtval].np_val > Revmax[rtype] ) X rtval--; X if ( rtval != origrtval ) { X setval("reverbtime",rtval); X showparam(parmindex("reverbtime"),0); X } X return(rtval); X} X X#define NUMBOOST 25 Xstruct numpair Boost[] = { X0,-12, 11,-11, 21,-10, 31,-9, 41,-8, X52,-7, 62,-6, 72,-5, 82,-4, 92,-3, X103,-2, 113,-1, 123,0, 133,1, 143,2, X153,3, 164,4, 174,5, 184,6, 194,7, X204,8, 215,9, 225,10, 235,11, 245,12, X-1, -1 X}; X Xd5bcin(v) X{ X register int n; X X for ( n=0; Boost[n].np_byte >= 0 ; n++ ) { X if ( v < Boost[n].np_byte ) X break; X } X return(n-1); X} Xd5bcout(v) X{ X return(Boost[v].np_byte); X} X Xchar * Xvisd5bc(v) X{ X if ( v >= 0 && v < NUMBOOST ) { X sprintf(D5buff,"%d",Boost[v].np_val); X return(D5buff); X } X else X return("??"); X} X Xchar * Xvisd5q(v) X{ X if ( v==0 ) X return("0.2"); X else if ( v <= 3 ) X return("0.3"); X else if ( v <= 90 ) { X sprintf(D5buff,"%d.%d",v/10,v%10); X return(D5buff); X } X else X return("??"); X} X Xchar * Xvisd5fm(v) X{ X int rem; X X if ( v < 0 || v > 127 ) X return("??"); X v = Freqmid[v]; X if ( v < 100 ) X sprintf(D5buff,"0.%d",v); X else if ( v < 1000 ) { X rem = v%100; X sprintf(D5buff,(rem<10)?"%d.0%d":"%d.%d",v/100,rem); X } X else X sprintf(D5buff,"%d.%d",v/100,(v/10)%10); X return(D5buff); X} X Xinitdp5() X{ X static int initdone = 0; X int n1, n2, n; X FILE *f; X X if ( initdone ) X return; X initdone = 1; X printf("Reading data from 'glibinit.dp5' ...\n"); X X Chdepth = (struct numpair *) alloc(NUMCD * sizeof(struct numpair)); X Chrate = (struct numpair *) alloc(NUMCR * sizeof(struct numpair)); X Chfeed = (int *) alloc(NUMCF * sizeof(int)); X Nlrevtime = (struct numpair *) alloc(NUMNLRT * sizeof(struct numpair)); X Revtime = (struct numpair *) alloc(NUMRT * sizeof(struct numpair)); X Freqmid = (int *) alloc(NUMFREQ * sizeof(int)); X Gatetime = (int *) alloc(NUMGATE * sizeof(int)); X Hf = (struct hfpair *) alloc(NUMHF * sizeof(struct hfpair)); X Dtime = (int *) alloc(NUMDT * sizeof(int)); X Predly = (int *) alloc(NUMPD * sizeof(int)); X X OPENTEXTFILE(f,"glibinit.dp5","r"); X if ( f == NULL ) { X fprintf(stderr,"Hey, 'initdata.dp5' can't be opened!\n"); X millisleep(2000); X return; X } X X if ( getcomment(f) ) X goto err; X for ( n=0; n<NUMCD; n++ ) { X if ( fscanf(f,"%d,%d",&n1,&n2) != 2 ) X goto err; X Chdepth[n].np_byte = n1; X Chdepth[n].np_val = n2; X } X if ( getcomment(f) ) X goto err; X for ( n=0; n<NUMFREQ; n++ ) { X if ( fscanf(f,"%d",&n1) != 1 ) X goto err; X Freqmid[n] = n1; X } X if ( getcomment(f) ) X goto err; X for ( n=0; n<NUMHF; n++ ) { X if ( fscanf(f,"%d,%d",&n1,&n2) != 2 ) X goto err; X Hf[n].hf_byte = n1; X Hf[n].hf_val = n2; X } X if ( getcomment(f) ) X goto err; X for ( n=0; n<NUMGATE; n++ ) { X if ( fscanf(f,"%d",&n1) != 1 ) X goto err; X Gatetime[n] = n1; X } X if ( getcomment(f) ) X goto err; X for ( n=0; n<NUMCR; n++ ) { X if ( fscanf(f,"%d,%d",&n1,&n2) != 2 ) X goto err; X Chrate[n].np_byte = n1; X Chrate[n].np_val = n2; X } X if ( getcomment(f) ) X goto err; X for ( n=0; n<NUMNLRT; n++ ) { X if ( fscanf(f,"%d,%d",&n1,&n2) != 2 ) X goto err; X Nlrevtime[n].np_byte = n1; X Nlrevtime[n].np_val = n2; X } X if ( getcomment(f) ) X goto err; X for ( n=0; n<NUMCF; n++ ) { X if ( fscanf(f,"%d",&n1) != 1 ) X goto err; X Chfeed[n] = n1; X } X if ( getcomment(f) ) X goto err; X for ( n=0; n<NUMRT; n++ ) { X if ( fscanf(f,"%d,%d",&n1,&n2) != 2 ) X goto err; X Revtime[n].np_byte = n1; X Revtime[n].np_val = n2; X } X if ( getcomment(f) ) X goto err; X for ( n=0; n<NUMDT; n++ ) { X if ( fscanf(f,"%d",&n1) != 1 ) X goto err; X Dtime[n] = n1; X } X if ( getcomment(f) ) X goto err; X for ( n=0; n<NUMPD; n++ ) { X if ( fscanf(f,"%d",&n1) != 1 ) X goto err; X Predly[n] = n1; X } X if ( getcomment(f) ) X goto err; X X return; X err: X fprintf(stderr,"Hey, something's wrong with initdata.dp5!\n"); X millisleep(2000); X return; X} Xgetcomment(f) XFILE *f; X{ X char buff[BUFSIZ]; X X if ( fscanf(f,"%s",buff) != 1 || *buff != '#' ) X return(1); X return(0); X} END_OF_FILE if test 18882 -ne `wc -c <'dep5.mnu'`; then echo shar: \"'dep5.mnu'\" unpacked with wrong size! fi # end of 'dep5.mnu' fi if test -f 'mac-mdr.a' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mac-mdr.a'\" else echo shar: Extracting \"'mac-mdr.a'\" \(14436 characters\) sed "s/^X//" >'mac-mdr.a' <<'END_OF_FILE' X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; X; $Id: mac-mdr.a,v 1.6 89/05/06 17:13:33 lee Exp $ X; X; midi driver X; X; also includes a millisecond relative-time counter with 5 mS resolution X; X; Steven A. Falco - moss!saf X; 3/6/87 X; $Log: mac-mdr.a,v $ X; Revision 1.6 89/05/06 17:13:33 lee X; rel. to comp.sources.misc X; X; X; portions taken from article in nov 85 mactutor by Kirk Austin X; X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; X; X BRANCH SHORT ; use short displacements X CASE ON ; be case-sensitive X STRING PASCAL ; use pascal-style strings X; X; timer constants X; XTIME_INC EQU 5 ; granularity of timer XMS5 EQU 3917 ; VIA tics per 5 ms (1.2766 uS each) X; XT1VEC EQU 24 ; lvl1 trap table offset XMAX_BYTE EQU $FF ; like it says XVIAT1EN EQU $C0 ; enable timer 1 interrupts XVIAT1DI EQU $40 ; diable timer 1 interrupts XVIARUN EQU $40 ; make T1 free-run XVIASTOP EQU $3F ; put T1 in single-shot mode X; X; queue lengths X; XTxQSize EQU $100 ; transmit buffer length XRxQSize EQU $100 ; receive buffer length X; X; queue state flags X; Xmidi_em EQU $FF ; queue is empty Xmidi_ne EQU $00 ; queue is not empty X; X; The following are stack offsets given that an item is passed X; by the MPW C compiler and LINK/UNLK is used. DANGER!!! MPW C X; always passes in a long value. X; X; Note that in Pascal, a byte is passed as a short rather than a long... X; so Get_Byte would be $9. Also, in C, the caller cleans up, while in X; Pascal the callee cleans up. X; XGet_Byte EQU $000B XGet_Short EQU $000A XGet_Long EQU $0008 X; X; select one based on oscillator frequency used in hardware X; X;C_baud EQU %01000100 ; 500 KHz XC_baud EQU %10000100 ; 1 MHz X;C_baud EQU %11000100 ; 2 MHz X; X; misc controls in SCC chip X; XNo_W_Req EQU 0 XRx_off EQU %11000000 XTx_off EQU %01100010 XTRxC EQU %00101000 XBrgen_off EQU 0 XRx_on EQU %11000001 XTx_on EQU %01101010 XDCD_int EQU %00001000 XRstExtSt EQU %00010000 XEnInt EQU %00010011 XMIntEn EQU %00001010 XEnMoInt EQU %00000001 XNo_Vec EQU %00000010 XaReset EQU %10000000 XrstTBE EQU $28 XrstEERR EQU $30 XNoData EQU $FFFF X; X; misc offsets in trap table X; XarxIO EQU 24 XatxIO EQU 16 XaspRC EQU 28 X; X; SR masks for interrupt control X; Xspl3 EQU $0300 ;set interrupt level to 3 X; X; SCC registers X; XSCC0 EQU 0 XSCC1 EQU 1 XSCC2 EQU 2 XSCC3 EQU 3 XSCC4 EQU 4 XSCC5 EQU 5 XSCC6 EQU 6 XSCC7 EQU 7 XSCC8 EQU 8 XSCC9 EQU 9 XSCC10 EQU 10 XSCC11 EQU 11 XSCC12 EQU 12 XSCC13 EQU 13 XSCC14 EQU 14 XSCC15 EQU 15 X; X; macro to enqueue a byte to be transmitted (can't use a subroutine X; 'cause we expect the stack to be in a certain state!) X; X MACRO X TxEnqueue X MOVE TxByteIn(A5),D0 ; where to put it (offset) X LEA TxQueue(A5),A2 ; base of queue X MOVE.B Get_Byte(A6),0(A2,D0) ; copy it from the stack to the queue X ADDQ #1,D0 ; bump offset X CMP #TxQSize,D0 ; did it wrap? X BNE @1 ; nope X MOVE #0,D0 ; you betcha' X@1 MOVE D0,TxByteIn(A5) ; replace it X ENDM X; X; macro for delay (SCC is slow compared to 68000) X; X MACRO X Delay X MOVE.L (SP),(SP) X ENDM X; X; macro to load an SCC register (double moves are on purpose - slow down) X; X MACRO X Lscc &sreg,&val X MOVE.B &sreg,D0 X MOVE.B D0,(A0) X Delay X MOVE.B &val,D0 X MOVE.B D0,(A0) X Delay X ENDM X; X; debug traps for Macsbug X; XDbgb OPWORD $A9FF ; breakpoint XDbgs OPWORD $ABFF ; print string and breakpoint X; X; debug macro X; X MACRO X Dbs &string X; PEA &string X; Dbgs X ENDM X; X; chip addresses and offsets X; X PRINT OFF X INCLUDE 'SysEqu.a' X PRINT ON X; X; this code must always be resident so we load it in Main segment to X; guarantee that. (Ever call an interrupt handler that wasn't resident?) X; X SEG 'Main' X; X; global area X; X EXPORT (midi_txst, midi_rxst, midi_time):DATA X; XCtlOffset DS.W 1 ; channel control offset XDataOffset DS.W 1 ; channel data offset XChnReset DS.B 1 ; SCC channel reset select XRxIntOffset DS.W 1 ; for dispatch table XTxIntOffset DS.W 1 ; likewise XSpecRecCond DS.W 1 ; and one more X; XTxQueue DS.B TxQSize ; Tx data queue Xmidi_txst DS.B 1 ; the queue state XTxByteIn DS.W 1 ; offset for enqueue XTxByteOut DS.W 1 ; offset for dequeue X; XRxQueue DS.B RxQSize ; and the Rx queue Xmidi_rxst DS.B 1 ; the queue state XRxByteIn DS.W 1 ; offset for enqueue XRxByteOut DS.W 1 ; offset for dequeue X; Xmidi_time DS.L 1 ; mS relative-time value Xold_via_v DS.L 1 ; old VIA vector X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; X; The following are interrupt handlers. The system saves registers X; D0-D3 and A0-A3 so we don't... X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; X X; X; handler for time increment task X; Xup_it PROC ENTRY X MOVEM.L A5,-(SP) ; we also use D0-D1/A0 X MOVE.L CurrentA5,A5 ; we need the globals X; X Dbs #'time interrupt' X; X MOVE.L VIA,A0 ; via base register X MOVE.L #vT1C,D0 ; low byte of counter X MOVE.B 0(A0,D0),D1 ; reading clears the interrupt X; X MOVEQ #TIME_INC,D0 ; how much? X ADD.L D0,midi_time(A5) ; kick it up X; X MOVEM.L (SP)+,A5 X RTS X ENDP X; X; interrupt handler for received characters X; XRxIntHand PROC ENTRY X MOVEM.L A5,-(SP) ; we also use D0-D1/A0-A2 X MOVE.L CurrentA5,A5 ; we need the globals X MOVE.L SCCRd,A0 ; hardware addresses X MOVE.L SCCWr,A1 X; X Dbs #'rx interrupt' X; X MOVE DataOffset(A5),D0 ; ... offset X MOVE.B 0(A0,D0),D1 ; read the data - it's here given the interrupt X Delay X LEA RxQueue(A5),A2 ; base of destination queue X MOVE RxByteIn(A5),D0 ; ... offset X MOVE.B D1,0(A2,D0) ; store it X MOVE.B #midi_ne,midi_rxst(A5) ; guaranteed not empty X ADDQ #1,D0 ; we filled one X CMP #RxQSize,D0 ; wrapped it? X BNE @1 ; not yet X MOVE #0,D0 ; yes - reset to top X; X@1 MOVE D0,RxByteIn(A5) ; replace the offset X; X MOVEM.L (SP)+,A5 ; restore context X RTS ; back to user X ENDP X; X; interrupt handler for transmitted characters X; XTxIntHand PROC ENTRY X MOVEM.L A5,-(SP) ; we also use D0-D1/A0-A2 X MOVE.L CurrentA5,A5 X MOVE.L SCCRd,A0 ; read base X MOVE.L SCCWr,A1 ; write base X; X Dbs #'tx interrupt' X; X TST.B midi_txst(A5) ; is there something to write? X BEQ @1 ; no - pity X MOVE CtlOffset(A5),D0 ; offset to control X MOVE.B #rstTBE,0(A1,D0) ; we saw the empty... X Delay X BRA TxIExit ; nothing to be done X; X@1 MOVE TxByteOut(A5),D0 ; offset of something to send X LEA TxQueue(A5),A2 ; base of queue X MOVE DataOffset(A5),D1 ; offset to hardware X MOVE.B 0(A2,D0),0(A1,D1) ; move it out X Delay X ADDQ #1,D0 ; we used it up X CMP #TxQSize,D0 ; wrapped? X BNE @2 ; no... X MOVE #0,D0 ; 'fraid so X; X@2 MOVE D0,TxByteOut(A5) ; remember position X MOVE TxByteIn(A5),D1 ; see about the input side X CMP D0,D1 ; now empty? X BNE TxIExit ; no - just exit X MOVE.B #midi_em,midi_txst(A5) ; it's empty X; XTxIExit X MOVEM.L (SP)+,A5 ; be polite X RTS X ENDP X; X; a stub for special conditions - we sort-of handle them X; XStub PROC ENTRY X MOVEM.L A5,-(SP) ; we also use A0-A1 X MOVE.L CurrentA5,A5 X MOVE.L SCCRd,A0 ; read base X MOVE.L SCCWr,A1 ; write base X; X Dbs #'stub interrupt' X; X MOVE CtlOffset(A5),D0 ; offset to control X MOVE.B #rstEERR,0(A1,D0) ; we saw the botch, clear it X Delay X MOVEM.L (SP)+,A5 X RTS X ENDP X; X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; X; The following routines interface to MPW C. It considers D0-D1/A0-A1 as X; scratch. So do we. Returned values are placed in D0 (32 bits always) X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; X; X; init routine - must call this first to set up stuff! X; Xmidi_init PROC EXPORT X MOVE #aCtl,CtlOffset(A5) X MOVE #aData,DataOffset(A5) X MOVE.B #aReset,ChnReset(A5) X MOVE #arxIO,RxIntOffset(A5) X MOVE #atxIO,TxIntOffset(A5) X MOVE #aspRC,SpecRecCond(A5) X; X MOVE SR,-(SP) ; save interrupts X ; we use D0-D1/A0-A1 X ORI #spl3,SR ; interrupts of 4 or better only X; X Dbs #'init routine' X; X MOVE.L SCCRd,A1 ; get base address X ADD CtlOffset(A5),A1 ; ... control X MOVE.B (A1),D0 ; dummy read to clear SCC WR0 X Delay X; X; set up SCC channel A X; X MOVE.L SCCWr,A0 ; another base address X ADD CtlOffset(A5),A0 ; ... control X Lscc #SCC9,ChnReset(A5) ; reset channel X Lscc #SCC4,#C_baud ; set clock rate X Lscc #SCC1,#No_W_Req ; no write request X Lscc #SCC3,#Rx_off ; turn it off X Lscc #SCC5,#Tx_off ; him too X Lscc #SCC9,#No_Vec ; not vectored interrupts X Lscc #SCC11,#TRxC ; set clock source X Lscc #SCC14,#Brgen_off ; no break gen X Lscc #SCC3,#Rx_on ; now turn channel back on X Lscc #SCC5,#Tx_on ; these on too X Lscc #SCC15,#DCD_int ; Mr. Mousie on X Lscc #SCC0,#RstExtSt ; reset ext status X Lscc #SCC0,#RstExtSt ; reset ext status X Lscc #SCC1,#EnInt ; enable interrupts X Lscc #SCC9,#MIntEn ; master interrupt X; X; install trap vectors X; X MOVE.L #Lvl2DT,A0 ; dispatch table X MOVE RxIntOffset(A5),D0 ; ... offset X LEA RxIntHand,A1 ; pointer to handler X MOVE.L A1,0(A0,D0) ; load the pointer into the dispatch table X MOVE TxIntOffset(A5),D0 ; ... offset X LEA TxIntHand,A1 ; another pointer X MOVE.L A1,0(A0,D0) ; load it X MOVE SpecRecCond(A5),D0 ; ... offset X LEA Stub,A1 ; dummy handler X MOVE.L A1,0(A0,D0) ; load it X; X; clear queues X; X CLR RxByteIn(A5) ; clear circ. buffer pointers X CLR RxByteOut(A5) X MOVE.B #midi_em,midi_rxst(A5) ; mark it empty X CLR TxByteIn(A5) X CLR TxByteOut(A5) X MOVE.B #midi_em,midi_txst(A5) ; mark it empty X; X; get the timer going X; X CLR.L midi_time(A5) ; start clean X; X; save old interrupt vector - write ours X MOVE.L #Lvl1DT,A0 ; via trap table base X MOVEQ #T1VEC,D0 ; offset to t1 trap X MOVE.L 0(A0,D0),old_via_v(A5) ; save the old one X LEA up_it,A1 ; our trap handler X MOVE.L A1,0(A0,D0) ; set our handler in place X; X MOVE.L VIA,A0 ; via base register X; X; set the mode of operation - free running X MOVE.L #vACR,D0 ; offset to ACR X MOVE.B 0(A0,D0),D1 ; read old acr value X AND.B #VIASTOP,D1 ; drop any existing T1 bits X OR.B #VIARUN,D1 ; set the free-run bit X MOVE.B D1,0(A0,D0) ; put it back X; X; set the latches and counters X MOVE.L #vT1C,D0 ; low byte of timer X MOVE.B #(MS5 ** MAX_BYTE),0(A0,D0) ; write low byte X MOVE.L #vT1CH,D0 ; high byte of timer X MOVE.B #((MS5 >> 8) ** MAX_BYTE),0(A0,D0) ; write high byte X; X MOVE.L #vIER,D0 ; enable/disable register X MOVE.B #VIAT1EN,0(A0,D0) ; enable that interrupt! X; X MOVE (SP)+,SR ; interrupts on X RTS X ENDP X; X; midi_tx - send a byte to the midi port (we expect the stack to contain a long) X; Xmidi_tx PROC EXPORT X LINK A6,#0 ; remember where our argument is X MOVE SR,-(SP) ; save interrupts X MOVEM.L A2,-(SP) ; we also use D0/A0-A1 X ORI #spl3,SR ; interrupts of 4 or better only X; X Dbs #'transmit routine' X; X TST.B midi_txst(A5) ; check the flag X BNE TxQE ; queue empty - send direct X ; something here - just add to queue X TxEnqueue X BRA TxExit ; go home X; XTxQE ; must write directly to device (maybe) X MOVE.L SCCRd,A0 ; read base X MOVE.L SCCWr,A1 ; write base X MOVE CtlOffset(A5),D0 ; ... offset X BTST.B #txBE,0(A0,D0) ; is the device ready X BNE FirstByte ; yes - do direct write X ; device busy - add to queue - interrupt will wake up X ; handler and send it out when the device is free X TxEnqueue X MOVE.B #midi_ne,midi_txst(A5) ; now it's not empty X BRA TxExit ; done X; XFirstByte ; it really wants this byte... X MOVE DataOffset(A5),D0 ; ... offset X Delay X MOVE.B Get_Byte(A6),0(A1,D0) ; copy it from the stack to the device X Delay X; XTxExit ; clean up the world X MOVEM.L (SP)+,A2 ; restore registers X MOVE (SP)+,SR ; and interrupts X UNLK A6 X RTS ; in C, the caller cleans up X ENDP X; X; midi_rx - get a byte from the port (leave it in D0 as a long) X; We return -1 if nothing is available X; Xmidi_rx PROC EXPORT X ; don't need link 'cause nothing is passed in X MOVE SR,-(SP) ; save the interrupts X MOVEM.L D2/A2,-(SP) ; we also use D0-D1/A0-A1 X ORI #spl3,SR ; interrupts of 4 or better only X; X Dbs #'receive routine' X; X TST.B midi_rxst(A5) ; any data available? X BEQ @1 ; yes X MOVE.W #NoData,D0 ; no-data flag X EXT.L D0 ; sign-extend it X BRA RxExit ; C returns stuff in D0 X; X@1 MOVE RxByteOut(A5),D2 ; ... offset X LEA RxQueue(A5),A2 ; and base X CLR.L D0 ; start off empty X MOVE.B 0(A2,D2),D0 ; get the byte X ADDQ #1,D2 ; up the offset X CMP #RxQSize,D2 ; wrapped around? X BNE @2 ; not yet X MOVE #0,D2 ; yes - reset it to the top X; X@2 MOVE D2,RxByteOut(A5) ; and save it X MOVE RxByteIn(A5),D1 ; now look at the input side X CMP D2,D1 ; is the queue now empty? X BNE RxExit ; no - don't worry about it X MOVE.B #midi_em,midi_rxst(A5) ; yes - set the flag X; XRxExit X MOVEM.L (SP)+,D2/A2 ; restore registers X MOVE (SP)+,SR ; and interrupts X RTS X ENDP X; X; reset the modem port - must call before quitting because the trap X; vectors will be invalid once we exit!!! X; Xmidi_reset PROC EXPORT X MOVE #aCtl,CtlOffset(A5) ; prepare globals X MOVE #aData,DataOffset(A5) X MOVE.B #aReset,ChnReset(A5) X MOVE #arxIO,RxIntOffset(A5) X MOVE #atxIO,TxIntOffset(A5) X MOVE #aspRC,SpecRecCond(A5) X; X MOVE SR,-(SP) ; save interrupts X ; we use A0 X ORI #spl3,SR ; interrupts of 4 or better only X; X Dbs #'reset routine' X; X MOVE.L SCCWr,A0 ; base for writing X ADD CtlOffset(A5),A0 ; and the offset X; X Lscc #SCC9,ChnReset(A5) ; reset channel X Lscc #SCC15,#DCD_int ; Mr. Mousie stays on X Lscc #SCC0,#RstExtSt ; reset ext status X Lscc #SCC0,#RstExtSt ; reset ext status X Lscc #SCC1,#EnMoInt ; enable mouse interrupts X Lscc #SCC9,#MIntEn ; master interrupt X; X; pull out the plug on the timer X; X; first disable interrupts X MOVE.L VIA,A0 ; base of via X MOVE.L #vIER,D0 ; interrupt control reg. X MOVE.B #VIAT1DI,0(A0,D0) ; kill the interrupts X; X; next set back to single shot mode X MOVE.L #vACR,D0 ; offset to ACR X MOVE.B 0(A0,D0),D1 ; read old acr value X AND.B #VIASTOP,D1 ; drop any existing T1 bits X MOVE.B D1,0(A0,D0) ; put it back X; X; set the latches to 0 X MOVE.L #vT1C,D0 ; lower latch/counter X CLR.B 0(A0,D0) ; clear it too X MOVE.L #vT1CH,D0 ; offset to upper latch/counter X CLR.B 0(A0,D0) ; clear it X; X; restore old trap vector X MOVE.L #Lvl1DT,A0 ; dispatch table X MOVEQ #T1VEC,D0 ; vector offset X MOVE.L old_via_v(A5),0(A0,D0) ; reset the vector X; X; We don't turn the other vectors back to where they were... X; We also don't leave any of our interrupts enabled so it's OK X; X MOVE (SP)+,SR ; interrupts on X RTS X ENDP X; X END X END_OF_FILE if test 14436 -ne `wc -c <'mac-mdr.a'`; then echo shar: \"'mac-mdr.a'\" unpacked with wrong size! fi # end of 'mac-mdr.a' fi if test -f 'tx81p.mnu' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'tx81p.mnu'\" else echo shar: Extracting \"'tx81p.mnu'\" \(14135 characters\) sed "s/^X//" >'tx81p.mnu' <<'END_OF_FILE' X/* $Id: tx81p.mnu,v 1.6 89/05/06 17:13:43 lee Exp $ X * GLIB - a Generic LIBrarian and editor for synths X * X * TX81Z routines for Performance parameters X * Tim Thompson X * modifications: Greg Lee X * $Log: tx81p.mnu,v $ X * Revision 1.6 89/05/06 17:13:43 lee X * rel. to comp.sources.misc X * X */ X X#define OVERLAY1 X X#include "glib.h" X#include <ctype.h> X Xchar *visnum(), *viseffect(), *visass(), *viskey(); Xchar *vischan(), *visnote(), *vistdetune(), *vistout(), *vislfo(); Xchar *visponoff(), *vispvoice(), *vispshift(); X Xstatic char Pbuff[17]; X X#define PMEMSIZE 76 X#define PCEDSIZE 110 X X#define RESERVESIZE 0 X X/* This array contains arbitrary screen labels */ Xstruct labelinfo Ltx81p[] = { X#MENU X X 1 2 3 4 5 6 7 8 X --- --- --- --- --- --- --- --- X Voice % % % % % % % % X X X X Max Notes % % % % % % % % X Receive Ch. % % % % % % % % X Limit Low % % % % % % % % X Limit High % % % % % % % % X Detune % % % % % % % % X Note Shift % % % % % % % % X Volume % % % % % % % % X Out Assign % % % % % % % % X LFO Select % % % % % % % % X Micro Tune % % % % % % % % X X X Micro Tune Table % X Micro Tune Key % X-------------------------+ Assign Mode % XAuto-Note: Pitch % | Effect Select % XVol % Dur % Chan % | X#END X-1,-1,NULL X}; X Xstruct paraminfo Ptx81p[] = { X/* XNAME TYPE POS MAX OFFSET MASK SHIFT ADHOC X */ X#O op1voice pvoice %% 159 0 X#O op2voice pvoice %% 159 0 X#O op3voice pvoice %% 159 0 X#O op4voice pvoice %% 159 0 X#O op5voice pvoice %% 159 0 X#O op6voice pvoice %% 159 0 X#O op7voice pvoice %% 159 0 X#O op8voice pvoice %% 159 0 X#O op1max num %% 8 0 X#O op2max num %% 8 0 X#O op3max num %% 8 0 X#O op4max num %% 8 0 X#O op5max num %% 8 0 X#O op6max num %% 8 0 X#O op7max num %% 8 0 X#O op8max num %% 8 0 X#O op1rec chan %% 16 0 X#O op2rec chan %% 16 0 X#O op3rec chan %% 16 0 X#O op4rec chan %% 16 0 X#O op5rec chan %% 16 0 X#O op6rec chan %% 16 0 X#O op7rec chan %% 16 0 X#O op8rec chan %% 16 0 X#O op1liml note %% 127 0 X#O op2liml note %% 127 0 X#O op3liml note %% 127 0 X#O op4liml note %% 127 0 X#O op5liml note %% 127 0 X#O op6liml note %% 127 0 X#O op7liml note %% 127 0 X#O op8liml note %% 127 0 X#O op1limh note %% 127 0 X#O op2limh note %% 127 0 X#O op3limh note %% 127 0 X#O op4limh note %% 127 0 X#O op5limh note %% 127 0 X#O op6limh note %% 127 0 X#O op7limh note %% 127 0 X#O op8limh note %% 127 0 X#O op1detune tdetune %% 14 0 X#O op2detune tdetune %% 14 0 X#O op3detune tdetune %% 14 0 X#O op4detune tdetune %% 14 0 X#O op5detune tdetune %% 14 0 X#O op6detune tdetune %% 14 0 X#O op7detune tdetune %% 14 0 X#O op8detune tdetune %% 14 0 X#O op1shift pshift %% 48 0 X#O op2shift pshift %% 48 0 X#O op3shift pshift %% 48 0 X#O op4shift pshift %% 48 0 X#O op5shift pshift %% 48 0 X#O op6shift pshift %% 48 0 X#O op7shift pshift %% 48 0 X#O op8shift pshift %% 48 0 X#O op1vol num %% 99 0 X#O op2vol num %% 99 0 X#O op3vol num %% 99 0 X#O op4vol num %% 99 0 X#O op5vol num %% 99 0 X#O op6vol num %% 99 0 X#O op7vol num %% 99 0 X#O op8vol num %% 99 0 X#O op1out tout %% 3 0 X#O op2out tout %% 3 0 X#O op3out tout %% 3 0 X#O op4out tout %% 3 0 X#O op5out tout %% 3 0 X#O op6out tout %% 3 0 X#O op7out tout %% 3 0 X#O op8out tout %% 3 0 X#O op1lfo lfo %% 3 0 X#O op2lfo lfo %% 3 0 X#O op3lfo lfo %% 3 0 X#O op4lfo lfo %% 3 0 X#O op5lfo lfo %% 3 0 X#O op6lfo lfo %% 3 0 X#O op7lfo lfo %% 3 0 X#O op8lfo lfo %% 3 0 X#O op1micro ponoff %% 1 0 X#O op2micro ponoff %% 1 0 X#O op3micro ponoff %% 1 0 X#O op4micro ponoff %% 1 0 X#O op5micro ponoff %% 1 0 X#O op6micro ponoff %% 1 0 X#O op7micro ponoff %% 1 0 X#O op8micro ponoff %% 1 0 X#O microtune num %% 12 0 X#O microkey key %% 11 0 X#O assmode ass %% 1 0 X#O autopitch num %% 127 -60 X#O effect effect %% 3 0 X#O autochan num %% 16 -1 *5 X#O autodur num %% 20 -5 *5 X#O autovol num %% 127 -63 XNULL,NULL,-1,-1,-1,-1,visnum,0,0,0,0 X}; X X Xchar *tx81voices[] = { X "GrandPiano", "Uprt piano", "Deep Grd", "HonkeyTonk", "Elec Grand", X "Fuzz Piano", "SkoolPiano", "Thump Pno", "LoTine81Z", "HiTine81Z", X "ElectroPno", "NewElectro", "DynomiteEP", "DynoWurlie", "Wood Piano", X "Reed Piano", "PercOrgan", "16 8 4 2 F", "PumpOrgan", "<6 Tease>", X "Farcheeza", "Small Pipe", "Big Church", "AnalogOrgn", "Thin Clav", X "EZ Clav", "Fuzz Clavi", "LiteHarpsi", "RichHarpsi", "Celeste", X "BriteCelst", "Squeezebox", X X "Trumpet81Z", "Full Brass", "Flugelhorn", "ChorusBras", "FrenchHorn", X "AtackBrass", "SpitBoneBC", "Horns BC", "MelloTenor", "RaspAlto", X "Flute", "Pan Floot", "Bassoon", "Oboe", "Clarinet", X "Harmonica", "DoubleBass", "BowCello", "BoxCello", "SoloViolin", X "HiString 1", "LowString", "Pizzicato", "Harp", "ReverbStrg", X "SynString", "Voices", "HarmoPad", "FanfarTpts", "HiString 2", X "PercFlute", "BreathOrgn", X X "NylonGuit", "Guitar #1", "TwelveStrg", "Funky Pick", "AllThatJaz", X "HeavyMetal", "Old Banjo", "Zither", "ElecBass 1", "SqncrBass", X "SynFunkBas", "ElecBass 2", "AnalogBass", "Jaco Bass", "LatelyBass", X "MonophBass", "StadiumSol", "TrumptSolo", "BCSexyPhon", "Lyrisyn", X "WarmSquare", "Sync Lead", "MellowSqar", "Jazz Flute", "HeavyLead", X "Java Jive", "Xylophone", "GreatVibes ", "Sitar", "Bell Pad", X "PlasticHit", "DigiAnnie", X X "BaadBreath", "VocalNuts", "KrstlChoir", "Metalimba", "WaterGlass", X "BowedBell", ">>WOW<<", "Fuzzy Koto", "Spc Midiot", "Gurgle", X "Hole in 1", "Birds", "MalibuNite", "Helicopter", "Flight Sim", X "Brthbells", "Storm Wind", "Alarm Call", "Racing Car", "Whistling", X "Space Talk", "Space Vibe", "Timpani", "FM Hi-Hats", "Bass Drum", X "Tube Bells", "Noise Shot", "Snare 1", "Snare 2", "Hand Drum", X "Synballs", "Efem Toms" X}; X X/* X * tx8pdin X * X * Take info from 'data' and stuff values in the P array, by using X * the setval (and setopval) functions. The data is in PMEM format. X */ X Xtx8pdin(data) Xchar *data; X{ X int dop, n, msb; X X for ( n=1; n<=8; n++ ) { X dop = (n-1)*8; X setopval(n,"max",data[0+dop] & 017); X msb = (data[0+dop]>>4)&01; X setopval(n,"voice",128*msb + (data[1+dop]&0177)); X setopval(n,"rec",data[2+dop] & 037); X setopval(n,"liml",data[3+dop] & 0177); X setopval(n,"limh",data[4+dop] & 0177); X setopval(n,"detune",data[5+dop] & 017); X setopval(n,"shift",data[6+dop] & 077); X setopval(n,"vol",data[7+dop] & 0177); X setopval(n,"out",(data[0+dop]>>5) & 03); X setopval(n,"lfo",(data[2+dop]>>5) & 03); X setopval(n,"micro",(data[6+dop]>>6) & 01); X } X setval("microtune",data[64] & 017); X setval("assmode",data[65] & 01); X setval("effect",(data[65]>>1) & 03); X setval("microkey",(data[65]>>3) & 017); X X setval("autochan",Channel); X} X X/* X * tx8pdout X * X * Take (possibly changed) parameters values out of the P array and X * put them back into 'data'. X */ X Xtx8pdout(data) Xchar *data; X{ X int dop, n, voicenum, msb; X X for ( n=1; n<=8; n++ ) { X dop = (n-1)*8; X voicenum = getopval(n,"voice"); X msb = (voicenum>>7)&01; X data[0+dop] = getopval(n,"max") | (msb<<4) X | getopval(n,"out")<<5; X data[1+dop] = voicenum & 0177; X data[2+dop] = getopval(n,"lfo")<<5 | getopval(n,"rec"); X data[3+dop] = getopval(n,"liml"); X data[4+dop] = getopval(n,"limh"); X data[5+dop] = getopval(n,"detune"); X data[6+dop] = getopval(n,"micro")<<6 | getopval(n,"shift"); X data[7+dop] = getopval(n,"vol"); X } X data[64] = getval("microtune"); X data[65] = getval("microkey")<<3 | getval("effect")<<1 X | getval("assmode"); X Channel = getval("autochan"); X} X Xtx8psedit(data) Xchar *data; X{ X char pdata[PCEDSIZE]; X int n, cksum, c; X char *p; X X clrdata(pdata,PCEDSIZE); X pmemtopced(data,pdata); X sendmidi(0xf0); X sendmidi(0x43); X sendmidi(Channel-1); /* channel # */ X sendmidi(0x7e); /* format type */ X sendmidi(0x00); /* byte count */ X sendmidi(0x78); /* byte count */ X p = "LM 8976PE"; X cksum = 0; X while ( (c=(int)(*p++)) != '\0' ) { X sendmidi(c); X cksum += c; X } X for ( n=0; n<PCEDSIZE; n++ ) { X c = (int)(pdata[n]); X sendmidi(c); X cksum += c; X } X sendmidi((-cksum) & 0x7f); X sendmidi(EOX); X} X X/* Convert PMEM to PCED format */ Xpmemtopced(indata,outdata) Xchar *indata, *outdata; X{ X int n, inop, outop; X X for ( n=1; n<=8; n++ ) { X inop = (n-1)*8; X outop = (n-1)*12; X X outdata[0+outop] = indata[0+inop] & 017; X X outdata[1+outop] = (indata[0+inop]>>4)&01; X outdata[2+outop] = indata[1+inop] & 0177; X outdata[3+outop] = indata[2+inop] & 037; X outdata[4+outop] = indata[3+inop] & 0177; X outdata[5+outop] = indata[4+inop] & 0177; X outdata[6+outop] = indata[5+inop] & 017; X outdata[7+outop] = indata[6+inop] & 077; X outdata[8+outop] = indata[7+inop] & 0177; X outdata[9+outop] = (indata[0+inop]>>5) & 03; X outdata[10+outop] = (indata[2+inop]>>5) & 03; X outdata[11+outop] = (indata[6+inop]>>6) & 01; X } X outdata[96] = indata[64] & 017; X outdata[97] = indata[65] & 01; X outdata[98] = (indata[65]>>1) & 03; X outdata[99] = (indata[65]>>3) & 017; X for ( n=0; n<10; n++ ) X outdata[100+n] = indata[66+n]; X} X X/* send a bulk performance dump to the tx81z */ Xtx8psbulk(data) Xchar *data; X{ X int c, v, n, cksum; X char *p; X X sendmidi(0xf0); X sendmidi(0x43); X sendmidi(Channel-1); /* Channel # */ X sendmidi(0x7e); X sendmidi(0x13); X sendmidi(0x0a); X p = "LM 8976PM"; X cksum = 0; X while ( (c=(int)(*p++)) != '\0' ) { X sendmidi(c); X cksum += c; X } X /* send 32 PMEM's worth of data */ X for ( v=0; v<32; v++ ) { X for ( n=0; n<PMEMSIZE; n++ ) { X /* 24 PMEM's are editable, but the bulk dump has 32 */ X if ( v >= 24 ) X c = 0; X else X c = VOICEBYTE(data,v,n); X sendmidi(c & 0xff); X cksum += c; X } X } X sendmidi((-cksum) & 0x7f); X sendmidi(0xf7); X return(0); X} X X/* Request and read a bulk performance dump from the TX81Z */ Xtx8pgbulk(data) Xchar *data; X{ X int c, n, v, b1, b2, cksum, ret = 1; X long begin, toolong; X char *p; X X flushmidi(); X X sendmidi(0xf0); X sendmidi(0x43); X sendmidi(0x20 | (Channel-1)); /* Channel # */ X sendmidi(0x7e); X p = "LM 8976PM"; X while ( (c=(int)(*p++)) != '\0' ) X sendmidi(c); X sendmidi(EOX); X X begin = milliclock(); X toolong = begin + 1000 * TIMEOUT; X X if (synthinfileflag) getmidi(); X X /* wait for the x43 byte starting the dump */ X while ( milliclock() < toolong ) { X if ( STATMIDI && (c=(getmidi() & 0xff)) == 0x43 ) X break; X } X if ( c != 0x43 ) { X Reason = "Timeout waiting for 0x43"; X goto getout; X } X /* get the 14 bytes preceeding the data */ X for ( cksum=n=0; n<14; n++ ) { X /* twiddle your thumbs, but not forever */ X while ( ! STATMIDI ) { X if ( milliclock() > toolong ) X goto timeout; /* the end of an era */ X } X c = getmidi(); X if(n >= 4) X cksum += c; /* start of LM... keyword */ X } X /* 32 memories are dumped */ X for ( v=0; v<32; v++ ) { X for ( n=0; n<PMEMSIZE; n++ ) { X /* twiddle your thumbs, but not forever */ X while ( ! STATMIDI ) { X if ( milliclock() > toolong ) X goto timeout; /* the end of an era */ X } X c = (getmidi() & 0xff); X /* Ignore non-data bytes ? */ X if ( c & 0x80 ) X continue; X /* compute checksum */ X cksum += c; X /* Only 24 memories are used */ X if ( v < 24 ) X VOICEBYTE(data,v,n) = c; X } X } Xtimeout: X if ( v < 32 ) { X Reason = "Timeout while reading!"; X goto getout; X } X b1 = (getmidi() & 0xff); /* Checksum */ X b2 = (getmidi() & 0xff); /* EOX */ X cksum = (-cksum) & 0x7f; /* convert to what we must match */ X if ( b2 != EOX ) X Reason = "EOX not received"; X else if ( b1 != cksum ) { X static char ckbuff[80]; X sprintf(ckbuff,"Checksum doesn't match (got %d expected %d)",b1,cksum); X /* Reason = "Checksum doesn't match"; */ X Reason = ckbuff; X } X else { X Reason = ""; X ret = 0; /* all's well */ X } Xgetout: X return(ret); X} X Xchar * Xtx8pnof(data) Xchar *data; X{ X int n; X X for ( n=0; n<10; n++ ) X Pbuff[n] = data[66+n]; X Pbuff[10] = '\0'; X return(Pbuff); X} X Xtx8psnof(data,name) Xchar *data, *name; X{ X int n; X X for ( n=0; name[n]!='\0' && n<10; n++ ) X data[66+n] = name[n]; X for ( ; n<10; n++ ) X data[66+n] = ' '; X} X Xchar * Xvisass(v) X{ X switch(v){ X case 0: return("normal"); X case 1: return("alternate"); X } X return(""); X} X Xchar * Xviskey(v) X{ X switch(v){ X case 0: return("C"); X case 1: return("C#"); X case 2: return("D"); X case 3: return("D#"); X case 4: return("E"); X case 5: return("F"); X case 6: return("F#"); X case 7: return("G"); X case 8: return("G#"); X case 9: return("A"); X case 10: return("A#"); X case 11: return("B"); X } X return(""); X} X Xchar * Xviseffect(v) X{ X switch(v){ X case 0: return("none"); X case 1: return("delay"); X case 2: return("pan"); X case 3: return("chord"); X } X return(""); X} X Xchar * Xvischan(v) X{ X if ( v >= 0 && v <= 15 ) { X sprintf(Pbuff,"%d",v+1); X return(Pbuff); X } X if ( v == 16 ) X return("omni"); X return(""); X} X Xchar * Xvisnote(v) X{ X int octave; X X octave = (v/12) - 2; X sprintf(Pbuff,"%s%d",viskey(v%12),octave); X return(Pbuff); X} X Xchar * Xvispshift(v) X{ X sprintf(Pbuff,"%d",v-24); X return(Pbuff); X} X Xchar * Xvistdetune(v) X{ X sprintf(Pbuff,"%d",v-7); X return(Pbuff); X} X Xchar * Xvistout(v) X{ X switch (v) { X case 0: return("off"); X case 1: return("I"); X case 2: return("II"); X case 3: return("I+II"); X } X return(""); X} X Xchar * Xvislfo(v) X{ X switch (v) { X case 0: return("off"); X case 1: return("inst1"); X case 2: return("inst2"); X case 3: return("vib"); X } X return(""); X} X Xchar * Xvisponoff(v) X{ X switch(v){ X case 0: return("off"); X case 1: return("on"); X } X return(""); X} X Xchar * Xvispvoice(v) X{ X char *p, *prefixes = "IABCD"; X int bank, vnum, vindex; X X bank = v/32; X vnum = (v%32) + 1; X sprintf(Pbuff,vnum<10?"%c0%d":"%c%d",prefixes[bank],vnum); X if ( bank > 0 ) { X vindex = (bank-1)*32+vnum-1; X if ( vindex >= 0 && vindex < 128 ) { X strcat(Pbuff,"~d~l~l~l"); X p = tx81voices[vindex]; X if ( strlen(p) <= 5 ) X strcat(Pbuff,p); X else { X char buff[11]; X strcpy(buff,p); X buff[5] = '\0'; X strcat(Pbuff,buff); X strcat(Pbuff,"~d~l~l~l~l~l"); X strcat(Pbuff,&p[5]); X } X } X } X return(Pbuff); X} END_OF_FILE if test 14135 -ne `wc -c <'tx81p.mnu'`; then echo shar: \"'tx81p.mnu'\" unpacked with wrong size! fi # end of 'tx81p.mnu' fi echo shar: End of archive 8 \(of 15\). cp /dev/null ark8isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 15 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0