source: buchla-68k/orig/RAM/DOPATCH.C@ 0acb7d0

Last change on this file since 0acb7d0 was 3ae31e9, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Imported original source code.

  • Property mode set to 100755
File size: 12.6 KB
Line 
1/*
2 =============================================================================
3 dopatch.c -- MIDAS-VII Patch facility -- execution functions
4 Version 15 -- 1988-11-15 -- D.N. Lynx Crowe
5 =============================================================================
6*/
7
8#define DEBUGPA 0
9
10#include "stddefs.h"
11#include "hwdefs.h"
12#include "fpu.h"
13#include "graphdef.h"
14#include "vsdd.h"
15#include "wordq.h"
16#include "patch.h"
17
18#include "midas.h"
19#include "ptdisp.h"
20#include "instdsp.h"
21#include "wsdsp.h"
22
23#if DEBUGPA
24extern short debugsw;
25
26short debugpa = 1;
27#endif
28
29#define ST_NUL 0x0000 /* no subaddress breakdown */
30#define ST_VGT 0x0001 /* break subaddress into voice, group */
31#define ST_PCT 0x0002 /* break subaddress into port, chan, trig */
32
33extern char *S1IoRec, *S2IoRec, *M1IoRec, *M2IoRec;
34
35unsigned short seqdupd; /* sequence display update flag */
36
37extern short bform; /* oscillator buffer format */
38extern short curinst; /* current instrument being edited */
39extern short curvce; /* current voice being edited */
40extern short timemlt; /* time multiplier */
41
42extern short expbit[]; /* FPU exponent bit table */
43extern short ins2grp[]; /* instrument to group assignments */
44extern short s_inst[]; /* instrument to voice assignments */
45extern short vce2grp[]; /* voice to group assignments */
46
47extern unsigned short seqflag[16]; /* sequencer flags */
48extern unsigned short seqline[16]; /* current sequencer line */
49extern unsigned short sregval[16]; /* register values */
50extern unsigned short trstate[16]; /* trigger states */
51
52extern struct wordq ptefifo; /* trigger fifo */
53extern struct instdef vbufs[]; /* voice buffers */
54extern struct wstbl wslib[]; /* waveshape library */
55
56char ledstat[24]; /* LED status */
57
58/*
59
60*/
61
62short frq2par[] = {1, 3, 5, 7}; /* Frq to par */
63
64short ind2par[] = {9, 11, 12, 13, 14, 15}; /* Ind to par */
65
66short cv2vce[] = {11, 10, 6, 8}; /* CV to voice */
67
68short lg2base[7] = { 0, 3, 7, 10, 14, 17, 21}; /* LED group bases */
69
70char vgtype[] = {
71
72 ST_NUL, /* PA_NULL */
73
74 ST_PCT, /* PA_KEY */
75 ST_PCT, /* PA_TRG */
76
77 ST_NUL, /* PA_PLS */
78 ST_NUL, /* PA_LED */
79 ST_NUL, /* PA_SLIN */
80 ST_NUL, /* PA_SCTL */
81 ST_NUL, /* PA_TUNE */
82 ST_NUL, /* PA_RSET */
83 ST_NUL, /* PA_RADD */
84
85 ST_VGT, /* PA_INST */
86 ST_VGT, /* PA_OSC */
87 ST_VGT, /* PA_WAVA */
88 ST_VGT, /* PA_WAVB */
89 ST_VGT, /* PA_CNFG */
90 ST_VGT, /* PA_LEVL */
91 ST_VGT, /* PA_INDX */
92 ST_VGT, /* PA_FREQ */
93 ST_VGT, /* PA_FILT */
94 ST_VGT, /* PA_FILQ */
95 ST_VGT, /* PA_LOCN */
96 ST_VGT, /* PA_DYNM */
97
98 ST_NUL, /* PA_AUX */
99 ST_NUL, /* PA_RATE */
100 ST_NUL, /* PA_INTN */
101 ST_NUL, /* PA_DPTH */
102 ST_NUL, /* PA_VOUT */
103};
104
105/*
106
107*/
108
109/*
110 =============================================================================
111 pdows() -- get a waveshape for a voice
112 =============================================================================
113*/
114
115pdows(slot, voice, wsn)
116short slot, voice, wsn;
117{
118 unsigned short *fpuws;
119
120 if (slot) { /* waveshape slot B */
121
122 vbufs[voice].idhwsb = wsn;
123
124 memcpyw(vbufs[voice].idhwvbf, &wslib[wsn],
125 NUMHARM + (2 * NUMWPNT));
126
127 fpuws = io_fpu + FPU_OWST + (voice << 9) + 1;
128
129 memcpyw(fpuws, vbufs[voice].idhwvbf, NUMWPNT);
130
131 *(fpuws - 1) = vbufs[voice].idhwvbf[0];
132 *(fpuws + NUMWPNT) = vbufs[voice].idhwvbf[NUMWPNT - 1];
133
134 } else { /* waveshape slot A */
135
136 vbufs[voice].idhwsa = wsn;
137
138 memcpyw(vbufs[voice].idhwvaf, &wslib[wsn],
139 NUMHARM + (2 * NUMWPNT));
140
141 fpuws = io_fpu + FPU_OWST + (voice << 9) + 0x0100 + 1;
142
143 memcpyw(fpuws, vbufs[curvce].idhwvaf, NUMWPNT);
144
145 *(fpuws - 1) = vbufs[voice].idhwvaf[0];
146 *(fpuws + NUMWPNT) = vbufs[voice].idhwvaf[NUMWPNT - 1];
147
148 }
149}
150
151/*
152
153*/
154
155/*
156 =============================================================================
157 pfpufn() -- process an FPU function operation for a patch
158 =============================================================================
159*/
160
161pfpufn(voice, par, dat1, dat2)
162unsigned short voice, par, dat1, dat2;
163{
164 register unsigned short *fpu;
165 short delay;
166
167 fpu = io_fpu + FPU_OFNC + (voice << 8) + (par << 4);
168
169 switch (dat1) {
170
171 case PSA_SRC: /* source */
172 break;
173
174 case PSA_MLT: /* multiplier */
175
176 *(fpu + (long)FPU_TSF1) = dat2;
177 break;
178
179 case PSA_TIM: /* time */
180
181 *(fpu + (long)FPU_TMNT) = (((long)dat2 & 0x0000FFF0L)
182 * ((long)timemlt & 0x0000FFFFL)) >> 15;
183
184 ++delay;
185
186 *(fpu + (long)FPU_TEXP) = expbit[dat2 & 0x000F];
187
188 break;
189
190 case PSA_VAL: /* value */
191
192 sendval(voice, par, dat2);
193 break;
194
195 case PSA_FNC: /* function */
196 break;
197
198 default: /* something weird got in here ... */
199 break;
200 }
201}
202
203/*
204
205*/
206
207/*
208 =============================================================================
209 pdoctl() -- do oscillator control for a patch entry
210 =============================================================================
211*/
212
213pdoctl(voice, osc, dat1, dat2)
214register short voice, osc, dat1, dat2;
215{
216 register struct instdef *ip;
217
218 ip = &vbufs[voice];
219 bform = dat1;
220 setoval(ip, osc, dat2 >> 1);
221}
222
223/*
224
225*/
226
227/*
228 =============================================================================
229 dopatch() -- execute a patch entry
230 =============================================================================
231*/
232
233dopatch(pp)
234register struct patch *pp;
235{
236 register unsigned short suba, dat1, dat2;
237 register short i, temp;
238 register char *ser, *iorec;
239 unsigned short chan, oldsr, osc, port, spec, sat,trig, vgr, vgn, vgt;
240 short baseled, curled, ledctl;
241
242 spec = PE_SPEC & pp->paspec; /* destination */
243 suba = pp->pasuba; /* sub address */
244 dat1 = pp->padat1; /* data word 1 */
245 dat2 = pp->padat2; /* data word 2 */
246
247 sat = vgtype[spec]; /* sub-address type */
248
249 if (ST_VGT & sat) { /* vg, osc sub-address types */
250
251 vgr = 0x00FF & (suba >> 8); /* voice / group */
252 osc = 0x00FF & suba; /* oscillator */
253
254 if (vgr > 11) { /* sort out voices from groups */
255
256 vgt = 1; /* group */
257 vgn = vgr - 12;
258
259 } else {
260
261 vgt = 0; /* voice */
262 vgn = vgr;
263 }
264
265 } else if (ST_PCT & sat) { /* port, chan, trig sub-address types */
266
267 port = 0x0003 & (suba >> 11); /* port */
268 chan = 0x000F & (suba >> 7); /* channel */
269 trig = 0x007F & suba; /* trigger */
270 }
271/*
272
273*/
274 switch (spec) { /* dispatch on destination */
275
276 case PA_KEY: /* key action */
277
278 if ((dat2 EQ 0) OR (dat2 EQ 2))
279 putwq(&ptefifo, suba & 0x1FFF); /* closure */
280
281 if ((dat2 EQ 0) OR (dat2 EQ 1))
282 putwq(&ptefifo, suba | 0x8000); /* release */
283
284 break;
285
286 case PA_TRG: /* trigger */
287
288 trig &= 0x000F;
289 trstate[trig] = dat2;
290
291 if (dat2)
292 putwq(&ptefifo, suba); /* closure */
293
294 seqdupd |= (1 << trig);
295 break;
296
297 case PA_PLS: /* pulse output */
298
299 if (suba) {
300
301 ser = &io_midi + 10L; /* pulse 2 */
302 iorec = M2IoRec;
303
304 } else {
305
306 ser = &io_midi + 2L; /* pulse 1 */
307 iorec = M1IoRec;
308 }
309
310 oldsr = setsr(0x2700); /* DISABLE INTERRUPTS */
311
312 temp = iorec[29]; /* get current CFR1 */
313
314 switch (dat2) { /* switch on operation */
315
316 case 0: /* transient */
317
318 *ser = temp | 0x0082; /* on */
319 *ser = (temp & 0x00FD) | 0x0080; /* off */
320 break;
321
322 case 1: /* off */
323
324 *ser = (temp & 0x00FD) | 0x0080; /* off */
325 break;
326
327 case 2: /* on */
328
329 *ser = temp | 0x0082; /* on */
330 break;
331 }
332
333 setsr(oldsr); /* RESTORE INTERRUPTS */
334
335 break;
336/*
337
338*/
339 case PA_LED: /* LED control */
340
341 baseled = lg2base[suba]; /* get base of LED group */
342
343 for (i = 0; i < (3 + (suba & 1)); i++) { /* scan LEDs */
344
345 curled = i + baseled;
346 ledctl = 0x0003 & (dat1 >> (14 - (i << 1)));
347
348 if (ledctl EQ 1) { /* on */
349
350 ledstat[curled] = TRUE;
351 io_leds = curled;
352
353 } else if (ledctl EQ 2) { /* off */
354
355 ledstat[curled] = FALSE;
356 io_leds = curled | 0x0080;
357
358 } else if (ledctl EQ 3) { /* toggle */
359
360 if (ledstat[curled]) { /* on -> off */
361
362 ledstat[curled] = FALSE;
363 io_leds = curled | 0x0080;
364
365 } else { /* off -> on */
366
367 ledstat[curled] = TRUE;
368 io_leds = curled;
369 }
370 }
371 }
372
373 break;
374
375 case PA_SLIN: /* sequence line */
376
377 seqline[suba] = dat1;
378 seqdupd |= (1 << suba);
379 break;
380
381 case PA_SCTL: /* sequence control */
382
383
384 if (dat2) { /* start */
385
386 seqflag[suba] |= (SQF_RUN|SQF_CLK);
387 seqtime[suba] = seqtab[seqline[suba]].seqtime;
388
389#if DEBUGPA
390 if (debugsw AND debugpa)
391 printf("dopatch($%08lX): SLIN %02u %03u %5u RUN\n",
392 pp, suba, seqline[suba], seqtime[suba]);
393#endif
394
395 } else { /* stop */
396
397 seqflag[suba] = 0;
398 seqtime[suba] = 0;
399
400#if DEBUGPA
401 if (debugsw AND debugpa)
402 printf("dopatch($%08lX): SLIN %02u %03u STOP\n",
403 pp, suba, seqline[suba]);
404#endif
405
406 }
407
408 seqdupd |= (1 << suba);
409 break;
410/*
411
412*/
413 case PA_TUNE: /* tuning table */
414
415 gettun(dat1);
416 break;
417
418 case PA_RSET: /* register set */
419
420 sregval[suba] = dat1 ? sregval[dat2] : dat2;
421 seqdupd |= (1 << suba);
422 break;
423
424 case PA_RADD: /* regsister add */
425
426 temp = sregval[suba] + (dat1 ? sregval[dat2] : dat2);
427
428 if (temp > 99)
429 temp = 99;
430 else if (temp < 0)
431 temp = 0;
432
433 sregval[suba] = temp;
434 seqdupd |= (1 << suba);
435 break;
436
437 case PA_INST: /* instrument select */
438
439 if (vgt) { /* group */
440
441 ins2grp[vgn] = (ins2grp[vgn] & 0xFF00) | dat1;
442 setv2gi(vgn);
443
444 } else { /* voice */
445
446 if (curvce EQ vgn)
447 curinst = dat1;
448
449 s_inst[vgn] = dat1;
450 execins(vgn, dat1, 1);
451 }
452
453 break;
454/*
455
456*/
457
458 case PA_OSC: /* oscillator control */
459
460 if (vgt) { /* group */
461
462 for (i = 0; i < 12; i++)
463 if (vce2grp[i] EQ (1 + vgn))
464 pdoctl(i, osc, dat1, dat2);
465
466 } else { /* voice */
467
468 pdoctl(vgn, osc, dat1, dat2);
469 }
470
471 break;
472/*
473
474*/
475 case PA_WAVA: /* waveshape A select */
476
477 if (vgt) { /* group */
478
479 for (i = 0; i < 12; i++)
480 if (vce2grp[i] EQ (1 + vgn))
481 pdows(0, i, dat1);
482
483 } else { /* voice */
484
485 pdows(0, vgn, dat1);
486 }
487
488 break;
489
490 case PA_WAVB: /* waveshape B select */
491
492 if (vgt) { /* group */
493
494 for (i = 0; i < 12; i++)
495 if (vce2grp[i] EQ (1 + vgn))
496 pdows(1, i, dat1);
497
498 } else { /* voice */
499
500 pdows(1, vgn, dat1);
501 }
502
503 break;
504
505 case PA_CNFG: /* configuration select */
506
507 if (vgt) {
508
509 for (i = 0; i < 12; i++)
510 if (vce2grp[i] EQ (1 + vgn)) {
511
512 vbufs[i].idhcfg = dat1;
513 dosync(i);
514 }
515 } else {
516
517 vbufs[vgn].idhcfg = dat1;
518 dosync(vgn);
519 }
520
521 break;
522/*
523
524*/
525 case PA_LEVL: /* level */
526
527 if (vgt) { /* group */
528
529 for (i = 0; i < 12; i++)
530 if (vce2grp[i] EQ (1 + vgn))
531 pfpufn(i, 2, dat1, dat2);
532
533 } else { /* voice */
534
535 pfpufn(vgn, 2, dat1, dat2);
536 }
537
538 break;
539
540 case PA_INDX: /* index */
541
542 if (vgt) { /* group */
543
544 for (i = 0; i < 12; i++)
545 if (vce2grp[i] EQ (1 + vgn))
546 pfpufn(i, ind2par[osc], dat1, dat2);
547
548 } else { /* voice */
549
550 pfpufn(vgn, ind2par[osc], dat1, dat2);
551 }
552
553 break;
554/*
555
556*/
557 case PA_FREQ: /* frequency */
558
559 if (vgt) { /* group */
560
561 for (i = 0; i < 12; i++)
562 if (vce2grp[i] EQ (1 + vgn))
563 pfpufn(i, frq2par[osc], dat1, dat2);
564
565 } else { /* voice */
566
567 pfpufn(vgn, frq2par[osc], dat1, dat2);
568 }
569
570 break;
571
572 case PA_FILT: /* filter frequency */
573
574 if (vgt) { /* group */
575
576 for (i = 0; i < 12; i++)
577 if (vce2grp[i] EQ (1 + vgn))
578 pfpufn(i, 10, dat1, dat2);
579
580 } else { /* voice */
581
582 pfpufn(vgn, 10, dat1, dat2);
583 }
584
585 break;
586/*
587
588*/
589 case PA_FILQ: /* filter resonance */
590
591 if (vgt) { /* group */
592
593 for (i = 0; i < 12; i++)
594 if (vce2grp[i] EQ (1 + vgn))
595 pfpufn(i, 6, dat1, dat2);
596
597 } else { /* voice */
598
599 pfpufn(vgn, 6, dat1, dat2);
600 }
601
602 break;
603
604 case PA_LOCN: /* location */
605
606 if (vgt) { /* group */
607
608 for (i = 0; i < 12; i++)
609 if (vce2grp[i] EQ (1 + vgn))
610 pfpufn(i, 4, dat1, dat2);
611
612 } else { /* voice */
613
614 pfpufn(vgn, 4, dat1, dat2);
615 }
616
617 break;
618/*
619
620*/
621 case PA_DYNM: /* dynamics */
622
623 if (vgt) { /* group */
624
625 for (i = 0; i < 12; i++)
626 if (vce2grp[i] EQ (1 + vgn))
627 pfpufn(i, 8, dat1, dat2);
628
629 } else { /* voice */
630
631 pfpufn(vgn, 8, dat1, dat2);
632 }
633
634 break;
635
636 case PA_AUX: /* auxiliary control */
637
638 pfpufn(9, 0, dat1, dat2);
639 break;
640
641 case PA_RATE: /* phase shifter rate */
642
643 pfpufn(2, 0, dat1, dat2);
644 break;
645
646 case PA_INTN: /* phase shifter intensity */
647
648 pfpufn(1, 0, dat1, dat2);
649 break;
650
651 case PA_DPTH: /* phase shifter depth */
652
653 pfpufn(3, 0, dat1, dat2);
654 break;
655
656 case PA_VOUT: /* control voltage output */
657
658 pfpufn(cv2vce[suba], 0, dat1, dat2);
659 break;
660
661 }
662}
Note: See TracBrowser for help on using the repository browser.