/***************************************************************************
 *                        Yamaha Voice Data Printer                        *
 *                             By Chuck Brand                              *
 *                        Copyright 1989,1991,1992                         *
 *               Written: Using Manx Aztec C Proffesional 5.2              *
 ***************************************************************************
 *                     Use : PrintDump [p] [P]                             *
 *                     Make: cc -so PrintDump                              *
 *                     Link: ln PrintDump.o -lm32 -lc32                    *
 ***************************************************************************/

#include "exec/types.h"
#include "exec/memory.h"
#include "exec/io.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"
#include "VMem.h"
#include "stdio.h"

#define BUFF_SIZE 4104

extern struct FileHandle *Open();
struct VMem *VM;

/* Table for Ratio Mode (CRS) */
static float Table[64] = {.50,.71,.78,.87,1.00,1.41,1.57,1.73,
  2.00,2.32,3.00,3.14,3.46,4.00,4.24,4.71,5.00,5.19,5.65,6.00,
  6.28,6.92,7.00,7.07,7.85,8.00,8.48,8.65,9.00,9.42,9.89,10.00,
  10.38,10.99,11.00,11.30,12.00,12.11,12.56,12.72,13.00,13.84,
  14.00,14.10,14.13,15.00,15.55,15.57,15.70,16.96,17.27,17.30,
  18.37,18.84,19.03,19.78,20.41,20.76,21.20,21.98,22.49,23.55,
  24.22,25.95};

/* Tables for Fix Mode (FIX) (FIXRNG) (CRS) */
int FixTable[16] = {8,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240};
int FixFine[8] = {1,2,4,8,16,32,64,128};

/* Text for text related parameters */
char *Rng[] = {" *** "," 255 "," 510 "," 1 K "," 2 K ",
               " 4 K "," 8 K "," 16K "," 32K "};
char *Switch[] = {"OFF","ON "};
char *PM[] = {"Poly","Mono"};
char *FC[] = {"***","POR","SUS","BTH"};
char *Wave[] = {"SAW","SQU","TRI","S/H"};
char *Port[] = {"FULL T.","FINGERED"};
char *Mode[] = {"Ratio","Fixed"};
char *EGS[] = {"OFF"," 48"," 24"," 12"};
char *WvForm[] = {"W1","W2","W3","W4","W5","W6","W7","W8"};
char *TRNS[] = {"C1 ","C#1","D1 ","D#1","E1 ","F1 ","F#1",
                "G1 ","G#1","A1 ","A#1","B1 ","C2 ","C#2",
                "D2 ","D#2","E2 ","F2 ","F#2","G2 ","G#2",
                "A2 ","A#2","B2 ","C3 ","C#3","D3 ","D#3",
                "E3 ","F3 ","F#3","G3 ","G#3","A3 ","A#3",
                "B3 ","C4 ","C#4","D4 ","D#4","E4 ","F4 ",
                "F#4","G4 ","G#4","A4 ","A#4","B4 ","C5"};

FILE *fp1;
int vnum;
char filename[15],header[15];

main(argc,argv)
int argc;
char *argv[];
{
struct FileHandle *fp;
UBYTE *buffer;
int len,choice,i;

/* This is my program and me */
   printf("                       Yamaha Voice Data Printer\n");
   printf("                             By Chuck Brand\n");
   printf("                        Copyright 1989,1991,1992\n\n\n");

/* Input filename of Bulk Dump */
   printf("Input Data Dump Filename : ");
   scanf("%s",filename);

   printf("\n\n");

/* Open the file */
   if((fp=Open(filename,MODE_OLDFILE))==0) {
      printf("Could not open file!!\n");
      Exit();
   }

/* Allocate buffer for Bulk Dump data, Read it in, then close file */
   buffer=(UBYTE *)AllocMem(BUFF_SIZE,MEMF_CLEAR);
   len=Read(fp,buffer,BUFF_SIZE);
   Close(fp);

   VM = buffer + 6;

   for(i=0;i<32;i+=2) {
      printf("#%2.2d - %10.10s                    ",i,VM->VNAME);
      VM+=1;
      printf("#%2.2d - %10.10s\n",i+1,VM->VNAME);
      VM+=1;
   }

/* Which voice do you want to see? */
   printf("Which voice  (99 for all) : ");
   scanf("%d",&choice);

/* 0 to 32 only, or 99 for all */
   if((choice < 0) || (choice > 32)) {
      if(choice != 99) {
         printf("Sorry Input 0 to 31 only!!!");
         Exit();
      }
   }

/* P or p on command line means send it to the printer */
   if((*argv[1] == 'p') || (*argv[1] == 'P')) {
         if((fp1=fopen("PRT:","w"))==NULL) {
            printf("Could not open printer!!\n");
            Close(fp);
            Exit();
         }
   }
   else {
         if((fp1=fopen("*","w"))==NULL) {
            printf("Could not open screen!!\n");
            Close(fp);
            Exit();
         }
   }

   VM = buffer + 6;

   if(choice == 99) {
      for(i=0;i<32;i++) {
         vnum = i;
         printit();
         VM+=1;
      }
   }
   else {
      VM+=(choice);
      vnum = choice;
      printit();
   }

   fclose(fp1);
   FreeMem(buffer,BUFF_SIZE);
}

/* Actual Print routine */

printit()
{
fprintf(fp1,"                              YAMAHA VOICE CHART\n\n");
fprintf(fp1,"     VOICE NAME : %.10s  ",VM->VNAME);
fprintf(fp1,"From : %-15s  Voice # %2d\n",filename,vnum);
fprintf(fp1,"     ALGORITHM  : %2d   FEEDBACK  : %2d  TRANSPOSE : %3s",
          ((VM->SFA & 7)+1),((VM->SFA & 0x38)>>3),TRNS[VM->TRPS]);
fprintf(fp1,"  CHORUS : %3s\n",Switch[(VM->CMSPP & 0x80)>>4]);
fprintf(fp1,"     REVERB     : %2d   PITCH BND : %2d  POLY/MONO : %4s\n\n",
          VM->REV,VM->PBR,PM[(VM->CMSPP & 8)>>3]);
fprintf(fp1,"               Op  1  Op  2  Op  3  Op  4\n");
fprintf(fp1,"               -----  -----  -----  -----\n");
fprintf(fp1,"     OUT      :  %2d     %2d     %2d     %2d\n\n",
   VM->OP1.OUT,VM->OP2.OUT,VM->OP3.OUT,VM->OP4.OUT);
fprintf(fp1,"     Envelope Generator\n     ------------------\n");
fprintf(fp1,"     AR       :  %2d     %2d     %2d     %2d\n",
   VM->OP1.AR,VM->OP2.AR,VM->OP3.AR,VM->OP4.AR);
fprintf(fp1,"     D1R      :  %2d     %2d     %2d     %2d\n",
   VM->OP1.D1R,VM->OP2.D1R,VM->OP3.D1R,VM->OP4.D1R);
fprintf(fp1,"     D2R      :  %2d     %2d     %2d     %2d\n",
   VM->OP1.D2R,VM->OP2.D2R,VM->OP3.D2R,VM->OP4.D2R);
fprintf(fp1,"     RR       :  %2d     %2d     %2d     %2d\n",
   VM->OP1.RR,VM->OP2.RR,VM->OP3.RR,VM->OP4.RR);
fprintf(fp1,"     D1L      :  %2d     %2d     %2d     %2d\n",
   VM->OP1.D1L,VM->OP2.D1L,VM->OP3.D1L,VM->OP4.D1L);
fprintf(fp1,"     EG Shift :  %3s    %3s    %3s    %3s\n\n",
   EGS[(VM->EFFOP1 & 0x30)>>4],EGS[(VM->EFFOP2 & 0x30)>>4],
   EGS[(VM->EFFOP3 & 0x30)>>4],EGS[(VM->EFFOP4 & 0x30)>>4]);
fprintf(fp1,"     Keyboard Scaling\n     ----------------\n");
fprintf(fp1,"     Level    :  %2d     %2d     %2d     %2d\n",
   VM->OP1.LS,VM->OP2.LS,VM->OP3.LS,VM->OP4.LS);
fprintf(fp1,"     Rate     :  %2d     %2d     %2d     %2d\n\n",
   ((VM->OP1.RD & 0x18)>>3),((VM->OP2.RD & 0x18)>>3),
   ((VM->OP3.RD & 0x18)>>3),((VM->OP4.RD & 0x18)>>3));
fprintf(fp1,"     Oscillator\n     ----------\n");
fprintf(fp1,"     Mode     : %5s  %5s  %5s  %5s\n",
   Mode[(VM->EFFOP1 & 8)>>3],Mode[(VM->EFFOP2 & 8)>>3],
   Mode[(VM->EFFOP3 & 8)>>3],Mode[(VM->EFFOP4 & 8)>>3]);
fprintf(fp1,"     FixRng   : %5s  %5s  %5s  %5s\n",
   Rng[(VM->EFFOP1 & 7)+((VM->EFFOP1 & 8)>>3)],
   Rng[(VM->EFFOP2 & 7)+((VM->EFFOP2 & 8)>>3)],
   Rng[(VM->EFFOP3 & 7)+((VM->EFFOP3 & 8)>>3)],
   Rng[(VM->EFFOP4 & 7)+((VM->EFFOP4 & 8)>>3)]);

printfreq();

fprintf(fp1,"     Waveform :  %2s     %2s     %2s     %2s\n",
   WvForm[(VM->OFOP1 & 0x70)>>4],WvForm[(VM->OFOP2 & 0x70)>>4],
   WvForm[(VM->OFOP3 & 0x70)>>4],WvForm[(VM->OFOP4 & 0x70)>>4]);
fprintf(fp1,"     Detune   :  %2d     %2d     %2d     %2d\n\n",
   (VM->OP1.RD & 7)-3,(VM->OP2.RD & 7)-3,
   (VM->OP3.RD & 7)-3,(VM->OP4.RD & 7)-3);
fprintf(fp1,"     Sensitivity\n     -----------\n");
fprintf(fp1,"     Key Vel.  :  %2d     %2d     %2d     %2d\n",
   VM->OP1.ABK & 0x07,VM->OP2.ABK & 0x07,
   VM->OP3.ABK & 0x07,VM->OP4.ABK & 0x07);
fprintf(fp1,"     EG Bias   :  %2d     %2d     %2d     %2d\n",
   ((VM->OP1.ABK & 0x38)>>3),((VM->OP2.ABK & 0x38)>>3),
   ((VM->OP3.ABK & 0x38)>>3),((VM->OP4.ABK & 0x38)>>3));
fprintf(fp1,"     AME       :  %2d     %2d     %2d     %2d\n",
   ((VM->OP1.ABK & 4)>>6),((VM->ABK & 4)>>6),
   ((VM->OP3.ABK & 4)>>6),((VM->ABK & 4)>>6));
fprintf(fp1,"     A Mod Sensitivity  : %2d     P Mod Sensitivity  : %2d\n\n",
   ((VM->PAL & 0x0c)>>2),((VM->PAL & 0x70)>>4));
fprintf(fp1,"     LFO\n     ---\n");
fprintf(fp1,"     Wave  : %3s      Speed : %2d     Delay : %2d     Sync : %3s\n",
   Wave[VM->PAL & 3],VM->LFS,VM->LFD,Switch[(VM->SFA & 0x40)>>6]);
fprintf(fp1,"     A Mod Depth  : %2d       P Mod Depth  : %2d\n\n",
   VM->AMD,VM->PMD);
fprintf(fp1,"     Pitch Envelope Generator\n     ------------------------\n");
fprintf(fp1,"     PR1   : %2d      PR2   : %2d     PR3   : %2d\n",
   VM->PR1,VM->PR2,VM->PR3);
fprintf(fp1,"     PL1   : %2d      PL2   : %2d     PL3   : %2d\n\n",
   VM->PL1,VM->PL2,VM->PL3);
fprintf(fp1,"     Modulation Wheel\n     ----------------\n");
fprintf(fp1,"     Pitch : %2d       Amplitude : %2d\n\n",
   VM->MWPTCH,VM->MWAMP);
fprintf(fp1,"     Portamento\n     ----------\n");
fprintf(fp1,"     Mode : %8s     Time : %2d\n\n",
   Port[VM->CMSPP & 1],VM->PORT);
fprintf(fp1,"     Foot Control\n     ------------\n");
fprintf(fp1,"     Assign : %3s  Vol : %2d   Pitch : %2d   Amp : %2d\n\n",
   FC[(VM->CMSPP & 6)>>1],VM->FCVOL,VM->FCPTCH,VM->FCAMP);
fprintf(fp1,"     Breath Control\n     --------------\n");
fprintf(fp1,"     Pitch : %2d   Amp : %2d   P Bias : %2d   EG Bias : %2d\n\n",
   VM->BCPTCH,VM->BCAMP,VM->BCPBIAS,VM->BCEBIAS);

return();
}

/* Calculate Freq. for Fix mode or Ratio for Ratio mode */

printfreq()
{
int range,coarse,fine;
long freq;

   fprintf(fp1,"     Freq     : ");

   if ((VM->EFFOP1 & 8)>>3 == 1) {
      range = (VM->EFFOP1 & 7);
      fine = (VM->OFOP1 & 0x0f) * FixFine[range];
      coarse = ((VM->OP1.CRS & 0x3c)>>2);
      freq = ((FixTable[coarse] * FixFine[range])+fine);
      fprintf(fp1,"%5d  ",freq);
   }
   if ((VM->EFFOP1 & 8)>>3 == 0)
      fprintf(fp1,"%-5.2f  ",
         Table[VM->OP1.CRS]+((VM->OFOP1 & 0x0f)*.06) +
         ((VM->EFFOP1 & 7) * .01));

   if ((VM->EFFOP2 & 8)>>3 == 1) {
      range = (VM->EFFOP2 & 7);
      fine = (VM->OFOP2 & 0x0f) * FixFine[range];
      coarse = ((VM->OP2.CRS & 0x3c)>>2);
      freq = ((FixTable[coarse] * FixFine[range])+fine);
      fprintf(fp1,"%5d  ",freq);
   }
   if ((VM->EFFOP2 & 8)>>3 == 0)
      fprintf(fp1,"%-5.2f  ",
         Table[VM->OP2.CRS]+((VM->OFOP2 & 0x0f)*.06) +
         ((VM->EFFOP2 & 7) * .01));

   if ((VM->EFFOP3 & 8)>>3 == 1) {
      range = (VM->EFFOP3 & 7);
      fine = (VM->OFOP3 & 0x0f) * FixFine[range];
      coarse = ((VM->OP3.CRS & 0x3c)>>2);
      freq = ((FixTable[coarse] * FixFine[range])+fine);
      fprintf(fp1,"%5d  ",freq);
   }
   if ((VM->EFFOP3 & 8)>>3 == 0)
      fprintf(fp1,"%-5.2f  ",
         Table[VM->OP3.CRS]+((VM->OFOP3 & 0x0f)*.06) +
         ((VM->EFFOP3 & 7) * .01));

   if ((VM->EFFOP4 & 8)>>3 == 1) {
      range = (VM->EFFOP4 & 7);
      fine = (VM->OFOP4 & 0x0f) * FixFine[range];
      coarse = ((VM->OP4.CRS & 0x3c)>>2);
      freq = ((FixTable[coarse] * FixFine[range])+fine);
      fprintf(fp1,"%5d\n",freq);
   }
   if ((VM->EFFOP4 & 8)>>3 == 0)
      fprintf(fp1,"%-5.2f\n",
         Table[VM->OP4.CRS]+((VM->OFOP4 & 0x0f)*.06) +
         ((VM->EFFOP4 & 7) * .01));

return();
}

