[3ae31e9] | 1 | /*
|
---|
| 2 | =============================================================================
|
---|
| 3 | thtest.c -- send, capture, and display MIDI data for Thunder checkout
|
---|
| 4 | See VERMSG below for version and date.
|
---|
| 5 |
|
---|
| 6 | Environment: Atari 1040ST, GEMDOS, Alcyon C.
|
---|
| 7 | =============================================================================
|
---|
| 8 | */
|
---|
| 9 |
|
---|
| 10 | #define VERMSG "thtest -- Version 4.01 -- 1990-04-25 -- D.N. Lynx Crowe"
|
---|
| 11 |
|
---|
| 12 | #include "stdio.h"
|
---|
| 13 | #include "osbind.h"
|
---|
| 14 | #include "ctype.h"
|
---|
| 15 |
|
---|
| 16 | #include "stddefs.h"
|
---|
| 17 |
|
---|
| 18 | #define void int /* 'cause we ain't got no steenking voids */
|
---|
| 19 |
|
---|
| 20 | #define MBUFSZ (unsigned short)(31*1024) /* MIDI buffer size */
|
---|
| 21 |
|
---|
| 22 | #define DEFUNIT 0 /* default Thunder unit number */
|
---|
| 23 | #define DEFCHAN 0 /* default Thunder base channel */
|
---|
| 24 |
|
---|
| 25 | #define MMCODE1 0x007F /* Buchla MIDI manufacturer ID byte 1 */
|
---|
| 26 | #define MMCODE2 0x007F /* Buchla MIDI manufacturer ID byte 2 */
|
---|
| 27 |
|
---|
| 28 | #define PRODUCT 0x0001 /* Buchla product code for Thunder */
|
---|
| 29 |
|
---|
| 30 | #define SNAPFILE "THTEST.TMP" /* snap file name */
|
---|
| 31 | #define FILE_1 "THTEST.FFF" /* config file name */
|
---|
| 32 | #define FILE_2 "THTEST.GGG" /* library file name */
|
---|
| 33 |
|
---|
| 34 | #define MAXNOL 16 /* max number of data bytes on a line */
|
---|
| 35 |
|
---|
| 36 | #define FORMAT1 "\n%5u %02.02x"
|
---|
| 37 | #define FORMAT2 " %02.02x"
|
---|
| 38 | #define FORMAT3 "\n%5u"
|
---|
| 39 |
|
---|
| 40 | struct iorec { /* structure for MIDI buffer description */
|
---|
| 41 |
|
---|
| 42 | char *ibuf; /* base address of buffer */
|
---|
| 43 | short ibufsz; /* buffer size in bytes */
|
---|
| 44 | short ibufhd; /* head index */
|
---|
| 45 | short ibuftl; /* tail index */
|
---|
| 46 | short ibuflo; /* low water mark index */
|
---|
| 47 | short ibufhi; /* high water mark index */
|
---|
| 48 | };
|
---|
| 49 |
|
---|
| 50 | extern char *malloc();
|
---|
| 51 |
|
---|
| 52 | void PrMIDI(); /* forward reference */
|
---|
| 53 | void cleanbf(); /* forward reference */
|
---|
| 54 |
|
---|
| 55 | int SetMBuf(); /* forward reference */
|
---|
| 56 | int midi_in(); /* forward reference */
|
---|
| 57 | int m_stat(); /* forward reference */
|
---|
| 58 |
|
---|
| 59 | FILE *ifp; /* input file pointer */
|
---|
| 60 | FILE *ofp; /* output file pointer */
|
---|
| 61 | FILE *sfp; /* snap file pointer */
|
---|
| 62 |
|
---|
| 63 | char *newbuf; /* expanded MIDI buffer pointer */
|
---|
| 64 | char *oldbuf; /* old MIDI buffer pointer */
|
---|
| 65 |
|
---|
| 66 | char sxhead[32]; /* SysEx message header buffer */
|
---|
| 67 |
|
---|
| 68 | unsigned short indx; /* MIDI input byte number */
|
---|
| 69 | unsigned short thsum; /* Thunder SysEx checksum */
|
---|
| 70 | unsigned short Addr; /* address input temporary */
|
---|
| 71 | unsigned short Chan; /* channel number input temporary */
|
---|
| 72 | unsigned short Ctrl; /* controller number input temporary */
|
---|
| 73 | unsigned short Data; /* data input temporary */
|
---|
| 74 | unsigned short Prog; /* program input temporary */
|
---|
| 75 | unsigned short Unit; /* unit number input temporary */
|
---|
| 76 | unsigned short Valu; /* value input temporary */
|
---|
| 77 |
|
---|
| 78 | short feseen; /* MIDI active sensing seen */
|
---|
| 79 | short mstate; /* output monitor state */
|
---|
| 80 | short nol; /* number of MIDI data bytes on the line */
|
---|
| 81 | short oldbsz; /* old MIDI buffer size */
|
---|
| 82 | short oldbhi; /* old MIDI buffer high water mark */
|
---|
| 83 | short oldblo; /* old MIDI buffer low water mark */
|
---|
| 84 | short thunit; /* Thunder unit number */
|
---|
| 85 | short thchan; /* Thunder base channel */
|
---|
| 86 |
|
---|
| 87 | struct iorec *m_buff; /* MIDI iorec pointer */
|
---|
| 88 |
|
---|
| 89 | char *helpms[] = {
|
---|
| 90 |
|
---|
| 91 | "\n",
|
---|
| 92 | "Escape exit this program\n",
|
---|
| 93 | "space pause output\n",
|
---|
| 94 | "/ clear buffer and screen\n",
|
---|
| 95 | "b set base channel\n",
|
---|
| 96 | "c request current Thunder config\n",
|
---|
| 97 | "e examine a word in the current Thunder config\n",
|
---|
| 98 | "f write THTEST.FFF to MIDI\n",
|
---|
| 99 | "g write THTEST.GGG to MIDI\n",
|
---|
| 100 | "h display this help message\n",
|
---|
| 101 | "l request Thunder library\n",
|
---|
| 102 | "m toggle output monitor state\n",
|
---|
| 103 | "p send program change\n",
|
---|
| 104 | "s set a word in the current Thunder config\n",
|
---|
| 105 | "u set Thunder unit number\n",
|
---|
| 106 | "v send control change\n",
|
---|
| 107 | "w write MIDI input buffer to snap file\n",
|
---|
| 108 | "\n",
|
---|
| 109 | (char *)NULL
|
---|
| 110 | };
|
---|
| 111 |
|
---|
| 112 | /* |
---|
| 113 |
|
---|
| 114 | */
|
---|
| 115 |
|
---|
| 116 | /*
|
---|
| 117 | =============================================================================
|
---|
| 118 | SendB() -- send a byte to the MIDI port and update the checksum
|
---|
| 119 | =============================================================================
|
---|
| 120 | */
|
---|
| 121 |
|
---|
| 122 | void
|
---|
| 123 | SendB(byte)
|
---|
| 124 | unsigned short byte;
|
---|
| 125 | {
|
---|
| 126 | Bconout(3, 0x00FF & byte);
|
---|
| 127 | thsum = 0x00FF & (thsum + byte);
|
---|
| 128 |
|
---|
| 129 | if (mstate)
|
---|
| 130 | printf("<%02.2x> ", 0x00FF & byte);
|
---|
| 131 | }
|
---|
| 132 |
|
---|
| 133 | /*
|
---|
| 134 | =============================================================================
|
---|
| 135 | SendM() -- send a byte string to the MIDI port -- Checksum NOT updated.
|
---|
| 136 | =============================================================================
|
---|
| 137 | */
|
---|
| 138 |
|
---|
| 139 | void
|
---|
| 140 | SendM(nb, adr)
|
---|
| 141 | unsigned short nb;
|
---|
| 142 | char *adr;
|
---|
| 143 | {
|
---|
| 144 | short c;
|
---|
| 145 |
|
---|
| 146 | while (nb-- > 0) {
|
---|
| 147 |
|
---|
| 148 | Bconout(3, c = 0x00FF & *adr++);
|
---|
| 149 |
|
---|
| 150 | if (mstate)
|
---|
| 151 | printf("<%02.2x> ", c);
|
---|
| 152 | }
|
---|
| 153 | }
|
---|
| 154 |
|
---|
| 155 | /*
|
---|
| 156 | =============================================================================
|
---|
| 157 | SendW() -- send a 16 bit word out to MIDI and update the checksum
|
---|
| 158 | =============================================================================
|
---|
| 159 | */
|
---|
| 160 |
|
---|
| 161 | void
|
---|
| 162 | SendW(wrd)
|
---|
| 163 | unsigned short wrd;
|
---|
| 164 | {
|
---|
| 165 | SendB(0x000F & (wrd >> 12)); /* send MS bits */
|
---|
| 166 | SendB(0x003F & (wrd >> 6)); /* send middle bits */
|
---|
| 167 | SendB(0x003F & wrd); /* send LS bits */
|
---|
| 168 | }
|
---|
| 169 |
|
---|
| 170 | /* |
---|
| 171 |
|
---|
| 172 | */
|
---|
| 173 |
|
---|
| 174 | /*
|
---|
| 175 | =============================================================================
|
---|
| 176 | ThSysEx() -- send a Thunder SysEx message
|
---|
| 177 | =============================================================================
|
---|
| 178 | */
|
---|
| 179 |
|
---|
| 180 | void
|
---|
| 181 | ThSysEx(mt, mp1, mp2)
|
---|
| 182 | unsigned short mt, mp1, mp2;
|
---|
| 183 | {
|
---|
| 184 | /* setup the SysEx header */
|
---|
| 185 |
|
---|
| 186 | sxhead[0] = 0x00F0;
|
---|
| 187 | sxhead[1] = 0x0000;
|
---|
| 188 | sxhead[2] = MMCODE1;
|
---|
| 189 | sxhead[3] = MMCODE2;
|
---|
| 190 | sxhead[4] = PRODUCT;
|
---|
| 191 | sxhead[5] = thunit;
|
---|
| 192 | sxhead[6] = mt;
|
---|
| 193 | thsum = mt & 0x00FF;
|
---|
| 194 |
|
---|
| 195 | switch (mt) {
|
---|
| 196 |
|
---|
| 197 | case 0: /* write word */
|
---|
| 198 | case 3: /* send word */
|
---|
| 199 | case 4: /* send current config */
|
---|
| 200 | case 5: /* send library */
|
---|
| 201 |
|
---|
| 202 | SendM(7, sxhead); /* send the header */
|
---|
| 203 |
|
---|
| 204 | if ((0 EQ mt) OR (3 EQ mt)) /* optional Address */
|
---|
| 205 | SendW(Addr);
|
---|
| 206 |
|
---|
| 207 | if (0 EQ mt) /* optional Data */
|
---|
| 208 | SendW(Data);
|
---|
| 209 |
|
---|
| 210 | Bconout(3, -thsum & 0x007F); /* checksum */
|
---|
| 211 | Bconout(3, 0x00F7); /* EOX */
|
---|
| 212 |
|
---|
| 213 | if (mstate)
|
---|
| 214 | printf("<%02.2x> <F7>", -thsum & 0x007F);
|
---|
| 215 |
|
---|
| 216 | break;
|
---|
| 217 |
|
---|
| 218 | case 1: /* write current config */
|
---|
| 219 | case 2: /* write library */
|
---|
| 220 | default:
|
---|
| 221 |
|
---|
| 222 | break;
|
---|
| 223 | }
|
---|
| 224 |
|
---|
| 225 | if (mstate)
|
---|
| 226 | printf("\n");
|
---|
| 227 | }
|
---|
| 228 |
|
---|
| 229 | /* |
---|
| 230 |
|
---|
| 231 | */
|
---|
| 232 |
|
---|
| 233 | /*
|
---|
| 234 | =============================================================================
|
---|
| 235 | GetUInt() -- get an unsigned integer parameter from the console
|
---|
| 236 | =============================================================================
|
---|
| 237 | */
|
---|
| 238 |
|
---|
| 239 | short
|
---|
| 240 | GetUInt(msg, parm)
|
---|
| 241 | char *msg;
|
---|
| 242 | unsigned short *parm;
|
---|
| 243 | {
|
---|
| 244 | register long iv;
|
---|
| 245 | register int ten;
|
---|
| 246 | register unsigned short ch;
|
---|
| 247 |
|
---|
| 248 | iv = 0L;
|
---|
| 249 | ten = 10;
|
---|
| 250 |
|
---|
| 251 | if ((char *)NULL NE msg)
|
---|
| 252 | printf("%s", msg);
|
---|
| 253 |
|
---|
| 254 | while (0x000D NE (ch = 0x00FF & Bconin(2))) {
|
---|
| 255 |
|
---|
| 256 | if (isdigit(ch)) { /* see if it's a digit */
|
---|
| 257 |
|
---|
| 258 | Bconout(2, ch); /* echo the character */
|
---|
| 259 |
|
---|
| 260 | iv = (iv * ten) + (ch - '0');
|
---|
| 261 |
|
---|
| 262 | if (iv > 65535L) { /* check for overflow */
|
---|
| 263 |
|
---|
| 264 | Bconout(2, '\r'); /* output CR/LF */
|
---|
| 265 | Bconout(2, '\n');
|
---|
| 266 |
|
---|
| 267 | return(FAILURE);
|
---|
| 268 | }
|
---|
| 269 |
|
---|
| 270 | } else { /* wasn't a digit */
|
---|
| 271 |
|
---|
| 272 | Bconout(2, '\r'); /* output CR/LF */
|
---|
| 273 | Bconout(2, '\n');
|
---|
| 274 |
|
---|
| 275 | return(FAILURE);
|
---|
| 276 | }
|
---|
| 277 | }
|
---|
| 278 |
|
---|
| 279 | Bconout(2, '\r'); /* output CR/LF */
|
---|
| 280 | Bconout(2, '\n');
|
---|
| 281 |
|
---|
| 282 | if (iv > 65535L) /* check for overflow */
|
---|
| 283 | return(FAILURE);
|
---|
| 284 |
|
---|
| 285 | *parm = (unsigned short)iv; /* update the parameter */
|
---|
| 286 |
|
---|
| 287 | return(SUCCESS);
|
---|
| 288 | }
|
---|
| 289 |
|
---|
| 290 | /* |
---|
| 291 |
|
---|
| 292 | */
|
---|
| 293 |
|
---|
| 294 | /*
|
---|
| 295 | =============================================================================
|
---|
| 296 | SetMBuf() -- set up MIDI buffer
|
---|
| 297 | =============================================================================
|
---|
| 298 | */
|
---|
| 299 |
|
---|
| 300 | int
|
---|
| 301 | SetMBuf()
|
---|
| 302 | {
|
---|
| 303 | unsigned short size;
|
---|
| 304 |
|
---|
| 305 | size = MBUFSZ; /* MIDI buffer */
|
---|
| 306 |
|
---|
| 307 | m_buff = (struct iorec *)Iorec(2); /* pointer to buffer descriptor */
|
---|
| 308 |
|
---|
| 309 | oldbuf = m_buff->ibuf;
|
---|
| 310 | oldbsz = m_buff->ibufsz;
|
---|
| 311 | oldbhi = m_buff->ibufhi;
|
---|
| 312 | oldblo = m_buff->ibuflo;
|
---|
| 313 |
|
---|
| 314 | if ((char *)NULL EQ (newbuf = (char *)malloc(size))) {
|
---|
| 315 |
|
---|
| 316 | printf ("ERROR -- unable to allocate MIDI buffer.\n");
|
---|
| 317 | return(FAILURE);
|
---|
| 318 | }
|
---|
| 319 |
|
---|
| 320 | /* clear out the buffer */
|
---|
| 321 |
|
---|
| 322 | m_buff->ibufhd = 0; /* reset the head index */
|
---|
| 323 | m_buff->ibuftl = 0; /* reset the tail index */
|
---|
| 324 |
|
---|
| 325 | /* we do this twice because we aren't disabling interrupts ... */
|
---|
| 326 |
|
---|
| 327 | m_buff->ibufhd = 0; /* reset the head index */
|
---|
| 328 | m_buff->ibuftl = 0; /* reset the tail index */
|
---|
| 329 |
|
---|
| 330 | m_buff->ibuf = newbuf; /* change address of buffer */
|
---|
| 331 | m_buff->ibufsz = size; /* change size of buffer */
|
---|
| 332 |
|
---|
| 333 | indx = 0; /* reset the byte index */
|
---|
| 334 |
|
---|
| 335 | return(SUCCESS);
|
---|
| 336 | }
|
---|
| 337 |
|
---|
| 338 | /*
|
---|
| 339 | =============================================================================
|
---|
| 340 | midi_in() -- get MIDI byte
|
---|
| 341 | =============================================================================
|
---|
| 342 | */
|
---|
| 343 |
|
---|
| 344 | int
|
---|
| 345 | midi_in()
|
---|
| 346 | {
|
---|
| 347 | return((int)Bconin(3) & 0x00FF);
|
---|
| 348 | }
|
---|
| 349 |
|
---|
| 350 |
|
---|
| 351 | /*
|
---|
| 352 | =============================================================================
|
---|
| 353 | PrMIDI() -- print a MIDI data byte
|
---|
| 354 | =============================================================================
|
---|
| 355 | */
|
---|
| 356 |
|
---|
| 357 | void
|
---|
| 358 | PrMIDI(M_Byte)
|
---|
| 359 | unsigned int M_Byte;
|
---|
| 360 | {
|
---|
| 361 | if ((0x00FF & M_Byte) EQ 0x00FE) {
|
---|
| 362 |
|
---|
| 363 | if (NOT feseen) {
|
---|
| 364 |
|
---|
| 365 | printf("\nActive sense is active\n");
|
---|
| 366 |
|
---|
| 367 | if ((FILE *)NULL NE ofp)
|
---|
| 368 | fprintf(ofp, "\nActive sense is active\n");
|
---|
| 369 | }
|
---|
| 370 |
|
---|
| 371 | nol = 0;
|
---|
| 372 | feseen = TRUE;
|
---|
| 373 |
|
---|
| 374 | } else {
|
---|
| 375 |
|
---|
| 376 | ++indx;
|
---|
| 377 |
|
---|
| 378 | if (0x0080 & M_Byte) { /* new status byte */
|
---|
| 379 |
|
---|
| 380 | printf(FORMAT1, indx, M_Byte);
|
---|
| 381 | nol = 0;
|
---|
| 382 |
|
---|
| 383 | if ((FILE *)NULL NE ofp)
|
---|
| 384 | fprintf(ofp, FORMAT1, indx, M_Byte);
|
---|
| 385 |
|
---|
| 386 | } else { /* data byte */
|
---|
| 387 |
|
---|
| 388 | if (++nol > MAXNOL) {
|
---|
| 389 |
|
---|
| 390 | printf(FORMAT3, indx);
|
---|
| 391 | nol = 1;
|
---|
| 392 |
|
---|
| 393 | if ((FILE *)NULL NE ofp)
|
---|
| 394 | fprintf(ofp, FORMAT3, indx);
|
---|
| 395 | }
|
---|
| 396 |
|
---|
| 397 | printf(FORMAT2, M_Byte);
|
---|
| 398 |
|
---|
| 399 | if ((FILE *)NULL NE ofp)
|
---|
| 400 | fprintf(ofp, FORMAT2, M_Byte);
|
---|
| 401 | }
|
---|
| 402 | }
|
---|
| 403 |
|
---|
| 404 | fflush(stdout);
|
---|
| 405 |
|
---|
| 406 | if ((FILE *)NULL NE ofp)
|
---|
| 407 | fflush(ofp);
|
---|
| 408 | }
|
---|
| 409 |
|
---|
| 410 |
|
---|
| 411 | /*
|
---|
| 412 | =============================================================================
|
---|
| 413 | m_stat() -- check midi status
|
---|
| 414 | =============================================================================
|
---|
| 415 | */
|
---|
| 416 |
|
---|
| 417 | int
|
---|
| 418 | m_stat()
|
---|
| 419 | {
|
---|
| 420 | return((int)Bconstat(3) ? TRUE : FALSE);
|
---|
| 421 | }
|
---|
| 422 |
|
---|
| 423 |
|
---|
| 424 | /*
|
---|
| 425 | =============================================================================
|
---|
| 426 | cleanbf() -- clean out MIDI buffer
|
---|
| 427 | =============================================================================
|
---|
| 428 | */
|
---|
| 429 |
|
---|
| 430 | void
|
---|
| 431 | cleanbf()
|
---|
| 432 | {
|
---|
| 433 | int mstat;
|
---|
| 434 |
|
---|
| 435 | printf("Clearing MIDI input buffer ...\n");
|
---|
| 436 | feseen = FALSE;
|
---|
| 437 |
|
---|
| 438 | /* clear out the buffer by resetting the head and tail indices */
|
---|
| 439 |
|
---|
| 440 | m_buff->ibufhd = 0; /* reset the head index */
|
---|
| 441 | m_buff->ibuftl = 0; /* reset the tail index */
|
---|
| 442 |
|
---|
| 443 | /* we do this twice because we aren't disabling interrupts ... */
|
---|
| 444 |
|
---|
| 445 | m_buff->ibufhd = 0; /* reset the head index */
|
---|
| 446 | m_buff->ibuftl = 0; /* reset the tail index */
|
---|
| 447 |
|
---|
| 448 | /* make sure it's really drained */
|
---|
| 449 |
|
---|
| 450 | mstat = m_stat();
|
---|
| 451 |
|
---|
| 452 | while (mstat) {
|
---|
| 453 |
|
---|
| 454 | midi_in();
|
---|
| 455 | mstat = m_stat();
|
---|
| 456 | }
|
---|
| 457 |
|
---|
| 458 | indx = 0;
|
---|
| 459 | }
|
---|
| 460 |
|
---|
| 461 | /* |
---|
| 462 |
|
---|
| 463 | */
|
---|
| 464 |
|
---|
| 465 | /*
|
---|
| 466 | =============================================================================
|
---|
| 467 | thtest -- send, capture, and display MIDI data for Thunder checkout
|
---|
| 468 | =============================================================================
|
---|
| 469 | */
|
---|
| 470 |
|
---|
| 471 | void
|
---|
| 472 | main(argc, argv)
|
---|
| 473 | int argc;
|
---|
| 474 | char *argv[];
|
---|
| 475 | {
|
---|
| 476 | unsigned short ch, runtag;
|
---|
| 477 | char **s;
|
---|
| 478 |
|
---|
| 479 | ofp = (FILE *)NULL;
|
---|
| 480 | thunit = DEFUNIT;
|
---|
| 481 | thchan = DEFCHAN;
|
---|
| 482 |
|
---|
| 483 | printf("\033E%s\n\n", VERMSG);
|
---|
| 484 | printf("Typing h gets you a list of commands\n\n");
|
---|
| 485 |
|
---|
| 486 | if (SetMBuf()) /* move MIDI buffer & increase its size */
|
---|
| 487 | exit(2);
|
---|
| 488 |
|
---|
| 489 | printf("%u byte MIDI buffer allocated at 0x%08.8lx\n",
|
---|
| 490 | MBUFSZ, (long)newbuf);
|
---|
| 491 |
|
---|
| 492 | cleanbf(); /* clear out MIDI buffer */
|
---|
| 493 |
|
---|
| 494 | if (argc EQ 2) {
|
---|
| 495 |
|
---|
| 496 | if ((FILE *)NULL EQ (ofp = fopen(argv[1], "w"))) {
|
---|
| 497 |
|
---|
| 498 | printf("\nERROR -- Unable to open \"%s\" for output.\n",
|
---|
| 499 | argv[1]);
|
---|
| 500 |
|
---|
| 501 | exit(2);
|
---|
| 502 |
|
---|
| 503 | } else {
|
---|
| 504 |
|
---|
| 505 | printf("Writing log to file \"%s\".\n", argv[1]);
|
---|
| 506 | }
|
---|
| 507 | }
|
---|
| 508 |
|
---|
| 509 | printf("\nReady.\n");
|
---|
| 510 | runtag = TRUE;
|
---|
| 511 |
|
---|
| 512 | while (runtag) {
|
---|
| 513 |
|
---|
| 514 | if (Bconstat(2)) {
|
---|
| 515 |
|
---|
| 516 | ch = 0x00FF & Bconin(2);
|
---|
| 517 |
|
---|
| 518 | switch (ch) {
|
---|
| 519 |
|
---|
| 520 | case '\033': /* escape */
|
---|
| 521 |
|
---|
| 522 | runtag = FALSE;
|
---|
| 523 | break;
|
---|
| 524 |
|
---|
| 525 | case ' ': /* space = pause */
|
---|
| 526 |
|
---|
| 527 | printf("PAUSED");
|
---|
| 528 | Bconin(2);
|
---|
| 529 | printf("\b\b\b\b\b\b \b\b\b\b\b\b");
|
---|
| 530 |
|
---|
| 531 | break;
|
---|
| 532 |
|
---|
| 533 | case '/': /* / = clear buffer and screen */
|
---|
| 534 |
|
---|
| 535 | cleanbf();
|
---|
| 536 | printf("\033E");
|
---|
| 537 | printf("Ready.\n");
|
---|
| 538 |
|
---|
| 539 | if ((FILE *)NULL NE ofp) {
|
---|
| 540 |
|
---|
| 541 | fprintf(ofp, "\n\nMIDI buffer flushed.\n\n");
|
---|
| 542 | fflush(ofp);
|
---|
| 543 | }
|
---|
| 544 |
|
---|
| 545 | break;
|
---|
| 546 |
|
---|
| 547 | case 'B':
|
---|
| 548 | case 'b': /* b = set base channel */
|
---|
| 549 |
|
---|
| 550 | if (SUCCESS EQ GetUInt("\nChan: ", &Chan)) {
|
---|
| 551 |
|
---|
| 552 | if ((Chan > 0) AND (Chan < 17))
|
---|
| 553 | thchan = Chan - 1;
|
---|
| 554 | else
|
---|
| 555 | printf("\nERROR: out of range (1..16)\n");
|
---|
| 556 | }
|
---|
| 557 |
|
---|
| 558 | printf("\nThunder base channel = %u\n",
|
---|
| 559 | 1 + thchan);
|
---|
| 560 |
|
---|
| 561 | break;
|
---|
| 562 |
|
---|
| 563 | case 'C':
|
---|
| 564 | case 'c': /* c = request current Thunder config */
|
---|
| 565 |
|
---|
| 566 | ThSysEx(4, 0, 0);
|
---|
| 567 | break;
|
---|
| 568 |
|
---|
| 569 | case 'E':
|
---|
| 570 | case 'e': /* e = examine a word in a Thunder config */
|
---|
| 571 |
|
---|
| 572 | if (SUCCESS EQ GetUInt("\nAddr: ", &Addr))
|
---|
| 573 | ThSysEx(3, Addr, 0);
|
---|
| 574 |
|
---|
| 575 | break;
|
---|
| 576 |
|
---|
| 577 | case 'F':
|
---|
| 578 | case 'f': /* f = write THTEST.FFF to MIDI */
|
---|
| 579 |
|
---|
| 580 | if ((FILE *)NULL EQ (ifp = fopenb(FILE_1, "r"))) {
|
---|
| 581 |
|
---|
| 582 | printf("\nERROR: Unable to open \"%s\" for input\n",
|
---|
| 583 | FILE_1);
|
---|
| 584 |
|
---|
| 585 | break;
|
---|
| 586 |
|
---|
| 587 | } else {
|
---|
| 588 |
|
---|
| 589 | while (0 EQ feof(ifp))
|
---|
| 590 | Bconout(3, 0x00FF & getc(ifp));
|
---|
| 591 |
|
---|
| 592 | fclose(ifp);
|
---|
| 593 |
|
---|
| 594 | printf("\nFile \"%s\" written to MIDI\n",
|
---|
| 595 | FILE_1);
|
---|
| 596 | }
|
---|
| 597 |
|
---|
| 598 | break;
|
---|
| 599 |
|
---|
| 600 | case 'G':
|
---|
| 601 | case 'g': /* g = write THTEST.GGG to MIDI */
|
---|
| 602 |
|
---|
| 603 | if ((FILE *)NULL EQ (ifp = fopenb(FILE_2, "r"))) {
|
---|
| 604 |
|
---|
| 605 | printf("\nERROR: Unable to open \"%s\" for input\n",
|
---|
| 606 | FILE_2);
|
---|
| 607 |
|
---|
| 608 | break;
|
---|
| 609 |
|
---|
| 610 | } else {
|
---|
| 611 |
|
---|
| 612 | while (0 EQ feof(ifp))
|
---|
| 613 | Bconout(3, 0x00FF & getc(ifp));
|
---|
| 614 |
|
---|
| 615 | fclose(ifp);
|
---|
| 616 |
|
---|
| 617 | printf("\nFile \"%s\" written to MIDI\n",
|
---|
| 618 | FILE_2);
|
---|
| 619 | }
|
---|
| 620 |
|
---|
| 621 | break;
|
---|
| 622 |
|
---|
| 623 | case 'H':
|
---|
| 624 | case 'h': /* h = display on-line help */
|
---|
| 625 |
|
---|
| 626 | s = helpms;
|
---|
| 627 |
|
---|
| 628 | while (*s)
|
---|
| 629 | printf("%s", *s++);
|
---|
| 630 |
|
---|
| 631 | break;
|
---|
| 632 |
|
---|
| 633 | case 'L':
|
---|
| 634 | case 'l': /* l = request Thunder library */
|
---|
| 635 |
|
---|
| 636 | ThSysEx(5, 0, 0);
|
---|
| 637 | break;
|
---|
| 638 |
|
---|
| 639 | case 'M':
|
---|
| 640 | case 'm': /* m = toggle output monitor state */
|
---|
| 641 |
|
---|
| 642 | mstate = NOT mstate;
|
---|
| 643 | break;
|
---|
| 644 |
|
---|
| 645 | case 'P':
|
---|
| 646 | case 'p': /* p = send program change */
|
---|
| 647 |
|
---|
| 648 | if (SUCCESS EQ GetUInt("\nProg: ", &Prog)) {
|
---|
| 649 |
|
---|
| 650 | if ((Prog GE 0) AND (Prog < 128)) {
|
---|
| 651 |
|
---|
| 652 | Bconout(3, 0x00C0 | (thchan & 0x000F));
|
---|
| 653 | Bconout(3, 0x007F & Prog);
|
---|
| 654 |
|
---|
| 655 | } else {
|
---|
| 656 |
|
---|
| 657 | printf("\nERROR: out of range (0..127)\n");
|
---|
| 658 | }
|
---|
| 659 | }
|
---|
| 660 |
|
---|
| 661 | break;
|
---|
| 662 |
|
---|
| 663 | case 'S':
|
---|
| 664 | case 's': /* s = set a word in a Thunder config */
|
---|
| 665 |
|
---|
| 666 | if (SUCCESS EQ GetUInt("\nAddr: ", &Addr)) {
|
---|
| 667 |
|
---|
| 668 | if (SUCCESS EQ GetUInt("Data: ", &Data))
|
---|
| 669 | ThSysEx(0, Addr, Data);
|
---|
| 670 | }
|
---|
| 671 |
|
---|
| 672 | break;
|
---|
| 673 |
|
---|
| 674 | case 'U':
|
---|
| 675 | case 'u': /* u = set Thunder unit number */
|
---|
| 676 |
|
---|
| 677 | if (SUCCESS EQ GetUInt("\nUnit: ", &Unit)) {
|
---|
| 678 |
|
---|
| 679 | if ((Unit > 0) AND (Unit < 10))
|
---|
| 680 | thunit = Unit - 1;
|
---|
| 681 | else
|
---|
| 682 | printf("\nERROR: out of range (1..9)\n");
|
---|
| 683 | }
|
---|
| 684 |
|
---|
| 685 | printf("\nThunder unit number = %u\n",
|
---|
| 686 | 1 + thunit);
|
---|
| 687 |
|
---|
| 688 | break;
|
---|
| 689 |
|
---|
| 690 | case 'v':
|
---|
| 691 | case 'V': /* v = send control change */
|
---|
| 692 |
|
---|
| 693 | if (SUCCESS EQ GetUInt("\nCtrl: ", &Ctrl)) {
|
---|
| 694 |
|
---|
| 695 | if ((Ctrl GE 0) AND (Ctrl < 128)) {
|
---|
| 696 |
|
---|
| 697 | if (SUCCESS EQ GetUInt("\nValue: ", &Valu)) {
|
---|
| 698 |
|
---|
| 699 | if ((Valu GE 0) AND (Valu < 128)) {
|
---|
| 700 |
|
---|
| 701 | Bconout(3, 0x00B0 | (thchan & 0x000F));
|
---|
| 702 | Bconout(3, 0x007F & Ctrl);
|
---|
| 703 | Bconout(3, 0x007F & Valu);
|
---|
| 704 |
|
---|
| 705 | } else {
|
---|
| 706 |
|
---|
| 707 | printf("\nERROR: out of range (0..127)\n");
|
---|
| 708 | }
|
---|
| 709 | }
|
---|
| 710 |
|
---|
| 711 | } else {
|
---|
| 712 |
|
---|
| 713 | printf("\nERROR: out of range (0..127)\n");
|
---|
| 714 | }
|
---|
| 715 | }
|
---|
| 716 |
|
---|
| 717 | break;
|
---|
| 718 |
|
---|
| 719 | case 'W':
|
---|
| 720 | case 'w': /* w = write to SNAPFILE */
|
---|
| 721 |
|
---|
| 722 | if ((FILE *)NULL EQ (sfp = fopenb(SNAPFILE, "w"))) {
|
---|
| 723 |
|
---|
| 724 | printf("ERROR -- Unable to open \"%s\" for output.\n",
|
---|
| 725 | SNAPFILE);
|
---|
| 726 |
|
---|
| 727 | exit(2);
|
---|
| 728 |
|
---|
| 729 | } else {
|
---|
| 730 |
|
---|
| 731 | printf("\n\nWriting to file \"%s\".\n", SNAPFILE);
|
---|
| 732 | }
|
---|
| 733 |
|
---|
| 734 | fwrite(newbuf + 1, indx, 1, sfp);
|
---|
| 735 |
|
---|
| 736 | fflush(sfp);
|
---|
| 737 | fclose(sfp);
|
---|
| 738 |
|
---|
| 739 | printf("\nFile written and closed.\n\n");
|
---|
| 740 | break;
|
---|
| 741 | }
|
---|
| 742 | }
|
---|
| 743 |
|
---|
| 744 | if (m_stat())
|
---|
| 745 | PrMIDI(midi_in());
|
---|
| 746 |
|
---|
| 747 | if ((FILE *)NULL NE ofp)
|
---|
| 748 | fflush(ofp);
|
---|
| 749 | }
|
---|
| 750 |
|
---|
| 751 | if ((FILE *)NULL NE ofp) { /* close the log file if it's open */
|
---|
| 752 |
|
---|
| 753 | fprintf(ofp, "\n");
|
---|
| 754 | fflush(ofp);
|
---|
| 755 | fclose(ofp);
|
---|
| 756 | }
|
---|
| 757 |
|
---|
| 758 | /* clear out the buffer */
|
---|
| 759 |
|
---|
| 760 | m_buff->ibufhd = 0; /* reset the head index */
|
---|
| 761 | m_buff->ibuftl = 0; /* reset the tail index */
|
---|
| 762 |
|
---|
| 763 | /* we do this twice because we aren't disabling interrupts ... */
|
---|
| 764 |
|
---|
| 765 | m_buff->ibufhd = 0; /* reset the head index */
|
---|
| 766 | m_buff->ibuftl = 0; /* reset the tail index */
|
---|
| 767 |
|
---|
| 768 | m_buff->ibufsz = oldbsz; /* restore the old buffer size */
|
---|
| 769 | m_buff->ibuf = oldbuf; /* restore the old buffer address */
|
---|
| 770 |
|
---|
| 771 | free(newbuf); /* give back the big MIDI buffer */
|
---|
| 772 |
|
---|
| 773 | /* close up shop and exit */
|
---|
| 774 |
|
---|
| 775 | printf("\n");
|
---|
| 776 | fflush(stdout);
|
---|
| 777 | exit(0);
|
---|
| 778 | }
|
---|