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

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

Zero redundant declarations.

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