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

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

Fixed dopatch.c.

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