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

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

Added missing includes and declarations.

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