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

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

Added include files for global functions and variables.

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