v06i109: glib part 8 of 15
Brandon S. Allbery - comp.sources.misc
allbery at uunet.UU.NET
Mon May 15 13:40:35 AEST 1989
Posting-number: Volume 6, Issue 109
Submitted-by: lee at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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
More information about the Comp.sources.misc
mailing list