/* dxget.c -- program to get Yamaha exclusive messages and write to file */ /***************************************************************************** * Change Log * Date | Change *-----------+----------------------------------------------------------------- * 13-Jun-86 | Created Change Log *****************************************************************************/ #include "cext.h" #include "stdio.h" #include "mpu.h" #include "midicode.h" #include "userio.h" #include "cmdline.h" #define buffsize 17000 byte midibuff[buffsize]; extern int xbufftai; extern int xbuffmask; extern byte *xbuff; extern byte *buff; int xflag; /* for debugging */ int debptr; /**************************************************************************** * Data for command line parsing ****************************************************************************/ #define nswitches 8 private char *switches[nswitches] = { "-help", "-miditrace", "-m", "-trace", "-t", "-block", "-d", "-debug" }; #define noptions 1 private char *options[noptions] = { "-tune" }; /***************************************************************************** * Routines local to this module *****************************************************************************/ private void instruct(); private boolean output(); /**************************************************************************** * instruct * Effect: prints instructions for this routine ****************************************************************************/ private void instruct() { printf("This program will let you save DX7 and TX816 voice programs.\n"); printf("To save DX7 programs, you must connect\n"); printf(" DX7 MIDI OUT to MPU 401 MIDI IN.\n"); printf("For TX816 programs, connect TX816 MIDI OUT to MPU 401 MIDI IN,\n"); printf(" and set the OUT SLOT (leftmost display) to the module\n"); printf(" from which you want data.\n"); printf("For DX7: push the orange FUNCTION key, then the green 8. Push 8\n"); printf(" repeatedly until the display says SYS INFO AVAIL or\n"); printf(" SYS INFO UNAVAIL. If the display says SYS INFO UNAVAIL,\n"); printf(" push YES to change the display to SYS INFO AVAIL.\n"); printf(" Now, select a voice with the INTERNAL or CARTRIDGE button\n"); printf(" followed by a (green) number.\n"); printf("For ALL DX7 voices: after getting the SYS INFO AVAIL display,\n"); printf(" push 8 again to get MIDI TRANSMIT ?. Push YES.\n"); printf("For TX816: Hold down SELECT until you see UT in the display.\n"); printf(" Let up on SELECT and then push it once more to get the\n"); printf(" flashing dU. Push YES to dump all data from this module.\n"); printf(" Hold down SELECT until you see digits in the display.\n"); printf("After data is dumped, dxget will tell you what it got and write\n"); printf(" data to a file. Use dxput to copy a file to a dx module.\n"); } /**************************************************************************** * main * Effect: main program -- prompt user for information and get data ****************************************************************************/ void main(argc, argv) int argc; char *argv[]; { FILE *fp; /* the output file */ int done = false; /* flag is true when user is done */ byte *msg; /* message pointer */ char filename[100]; /* the output file name */ char *s; /* the file name in the command line */ cl_init(switches, nswitches, options, noptions, argv, argc); if (cl_switch("-help")) instruct(); /* get input file name: */ filename[0] = 0; /* empty string */ if ((s = cl_arg(1)) != NULL) strcpy(filename, s); while (!done) { if (askbool("Do you want instructions", true)) instruct(); fp = fileopen(filename, "dx7", "w", "file name"); musicinit(); if (!midi_buffer(midibuff, buffsize)) printf("midi_buffer error\n"); while (getkey(false) != -1) ; exclusive(true); /* tell mpu401 to send exclusive data */ printf("\nReady for your data. Type space when you are done...\n"); done = false; while (!done) { if (kbhit()) done = (getch() == ' '); mpu_error_check(); /* look for buffer overflow */ } musicterm(); msg = midibuff; if (xbufftai == 0) printf("No data! Please start again.\n"); else while (output(fp, &msg, midibuff + xbufftai)) /* write messages */; fclose(fp); printf("DONE\n"); done = !askbool("Do you want to send another file", false); filename[0] = 0; /* force prompt for new file name */ } } /**************************************************************************** * output * Inputs: * FILE *fp: the file to write * byte **msg: pointer to the message to write * byte *msg_tail: points to byte after last byte of recorded data * Outputs: ** byte **msg: is advanced to byte after the last byte of the message * returns true if there is more data to output * Effect: * write data file using recorded data * Assumes: * fp is opened for writing * msg_tail > *msg ****************************************************************************/ private boolean output(fp, msg, msg_tail) FILE *fp; byte **msg; byte *msg_tail; { byte *this_msg = *msg; /* local message pointer */ int datalen; /* number of bytes in message */ int cksum; /* check sum of message */ int n; /* counts bytes printed on one line */ /* printf("*msg %x, this_msg %x, msg_tail %x\n", * *msg, this_msg, msg_tail); * printf("%d bytes to go.\n", msg_tail - this_msg); */ excldesc(this_msg); /* for (i = *base; i < how_many; i+=4) { * if (kbhit() && (getch() == ' ')) break; * printf("%d: %x %x %x %x\n", * i, * midibuff[i], * midibuff[i+1], * midibuff[i+2], * midibuff[i+3]); * } */ this_msg = *msg; /* printf("parity check\n");*/ datalen = (this_msg[4] << 7) + this_msg[5]; /* printf("datalen %x\n", datalen);*/ cksum = 0; for (n = 6; n < datalen+6; n++) { cksum = (cksum + this_msg[n]) & 0x7f; } /* printf("computed check sum %x, actual check sum %x\n", cksum, midibuff[datalen+6]);*/ if ((cksum + this_msg[datalen+6]) & 0x7f != 0) { fprintf(stderr, "Data has been garbled -- please start over.\n"); return false; } n = 0; do { /* always print first byte, */ /* then terminate after printing MIDI_EOX */ fprintf(fp, "%x ", *this_msg); if (n >= 15) { /* print 16 bytes per line */ n = 0; fprintf(fp, "\n"); } else n++; this_msg++; } while (this_msg < msg_tail && *(this_msg-1) != MIDI_EOX) ; fprintf(fp, "\n\n"); *msg = this_msg; return this_msg < msg_tail; }