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

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

Removed redundant declarations.

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