source: buchla-68k/ram/dopatch.c@ 0580615

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

Point of no return.

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