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

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

Removed form-feed comments.

  • Property mode set to 100644
File size: 10.8 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
31int8_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 uint16_t *fpuws;
75
76 if (slot) { /* waveshape slot B */
77
78 vbufs[voice].idhwsb = 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) = vbufs[voice].idhwvbf[0];
88 *(fpuws + NUMWPNT) = vbufs[voice].idhwvbf[NUMWPNT - 1];
89
90 } else { /* waveshape slot A */
91
92 vbufs[voice].idhwsa = 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) = vbufs[voice].idhwvaf[0];
102 *(fpuws + NUMWPNT) = 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(uint16_t voice, uint16_t par, uint16_t dat1, uint16_t dat2)
114{
115 register 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 + (int32_t)FPU_TSF1) = dat2;
128 break;
129
130 case PSA_TIM: /* time */
131
132 *(fpu + (int32_t)FPU_TMNT) = (((int32_t)dat2 & 0x0000FFF0L)
133 * ((int32_t)timemlt & 0x0000FFFFL)) >> 15;
134
135 ++delay;
136
137 *(fpu + (int32_t)FPU_TEXP) = expbit[dat2 & 0x000F];
138
139 break;
140
141 case PSA_VAL: /* value */
142
143 sendval(voice, par, 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 register uint16_t suba, dat1, dat2;
178 register int16_t i, temp;
179 register int8_t *ser, *iorec;
180 uint16_t chan, oldsr, osc, port, spec, sat,trig, vgr, vgn, vgt;
181 int16_t baseled, curled, ledctl;
182
183 spec = PE_SPEC & pp->paspec; /* destination */
184 suba = pp->pasuba; /* sub address */
185 dat1 = pp->padat1; /* data word 1 */
186 dat2 = pp->padat2; /* data word 2 */
187
188 sat = vgtype[spec]; /* sub-address type */
189
190 if (ST_VGT & sat) { /* vg, osc sub-address types */
191
192 vgr = 0x00FF & (suba >> 8); /* voice / group */
193 osc = 0x00FF & suba; /* oscillator */
194
195 if (vgr > 11) { /* sort out voices from groups */
196
197 vgt = 1; /* group */
198 vgn = vgr - 12;
199
200 } else {
201
202 vgt = 0; /* voice */
203 vgn = vgr;
204 }
205
206 } else if (ST_PCT & sat) { /* port, chan, trig sub-address types */
207
208 port = 0x0003 & (suba >> 11); /* port */
209 chan = 0x000F & (suba >> 7); /* channel */
210 trig = 0x007F & suba; /* trigger */
211 }
212
213 switch (spec) { /* dispatch on destination */
214
215 case PA_KEY: /* key action */
216
217 if ((dat2 EQ 0) OR (dat2 EQ 2))
218 putwq(&ptefifo, suba & 0x1FFF); /* closure */
219
220 if ((dat2 EQ 0) OR (dat2 EQ 1))
221 putwq(&ptefifo, suba | 0x8000); /* release */
222
223 break;
224
225 case PA_TRG: /* trigger */
226
227 trig &= 0x000F;
228 trstate[trig] = dat2;
229
230 if (dat2)
231 putwq(&ptefifo, suba); /* closure */
232
233 seqdupd |= (1 << trig);
234 break;
235
236 case PA_PLS: /* pulse output */
237
238 if (suba) {
239
240 ser = &io_midi + 10L; /* pulse 2 */
241 iorec = M2IoRec;
242
243 } else {
244
245 ser = &io_midi + 2L; /* pulse 1 */
246 iorec = M1IoRec;
247 }
248
249 oldsr = setsr(0x2700); /* DISABLE INTERRUPTS */
250
251 temp = iorec[29]; /* get current CFR1 */
252
253 switch (dat2) { /* switch on operation */
254
255 case 0: /* transient */
256
257 *ser = temp | 0x0082; /* on */
258 *ser = (temp & 0x00FD) | 0x0080; /* off */
259 break;
260
261 case 1: /* off */
262
263 *ser = (temp & 0x00FD) | 0x0080; /* off */
264 break;
265
266 case 2: /* on */
267
268 *ser = temp | 0x0082; /* on */
269 break;
270 }
271
272 setsr(oldsr); /* RESTORE INTERRUPTS */
273
274 break;
275
276 case PA_LED: /* LED control */
277
278 baseled = lg2base[suba]; /* get base of LED group */
279
280 for (i = 0; i < (3 + (suba & 1)); i++) { /* scan LEDs */
281
282 curled = i + baseled;
283 ledctl = 0x0003 & (dat1 >> (14 - (i << 1)));
284
285 if (ledctl EQ 1) { /* on */
286
287 ledstat[curled] = TRUE;
288 io_leds = curled;
289
290 } else if (ledctl EQ 2) { /* off */
291
292 ledstat[curled] = FALSE;
293 io_leds = curled | 0x0080;
294
295 } else if (ledctl EQ 3) { /* toggle */
296
297 if (ledstat[curled]) { /* on -> off */
298
299 ledstat[curled] = FALSE;
300 io_leds = curled | 0x0080;
301
302 } else { /* off -> on */
303
304 ledstat[curled] = TRUE;
305 io_leds = curled;
306 }
307 }
308 }
309
310 break;
311
312 case PA_SLIN: /* sequence line */
313
314 seqline[suba] = dat1;
315 seqdupd |= (1 << suba);
316 break;
317
318 case PA_SCTL: /* sequence control */
319
320
321 if (dat2) { /* start */
322
323 seqflag[suba] |= (SQF_RUN|SQF_CLK);
324 seqtime[suba] = seqtab[seqline[suba]].seqtime;
325
326#if DEBUGPA
327 if (debugsw AND debugpa)
328 printf("dopatch($%08lX): SLIN %02u %03u %5u RUN\n",
329 pp, suba, seqline[suba], seqtime[suba]);
330#endif
331
332 } else { /* stop */
333
334 seqflag[suba] = 0;
335 seqtime[suba] = 0;
336
337#if DEBUGPA
338 if (debugsw AND debugpa)
339 printf("dopatch($%08lX): SLIN %02u %03u STOP\n",
340 pp, suba, seqline[suba]);
341#endif
342
343 }
344
345 seqdupd |= (1 << suba);
346 break;
347
348 case PA_TUNE: /* tuning table */
349
350 gettun(dat1);
351 break;
352
353 case PA_RSET: /* register set */
354
355 sregval[suba] = dat1 ? sregval[dat2] : dat2;
356 seqdupd |= (1 << suba);
357 break;
358
359 case PA_RADD: /* regsister add */
360
361 temp = sregval[suba] + (dat1 ? sregval[dat2] : dat2);
362
363 if (temp > 99)
364 temp = 99;
365 else if (temp < 0)
366 temp = 0;
367
368 sregval[suba] = temp;
369 seqdupd |= (1 << suba);
370 break;
371
372 case PA_INST: /* instrument select */
373
374 if (vgt) { /* group */
375
376 ins2grp[vgn] = (ins2grp[vgn] & 0xFF00) | dat1;
377 setv2gi(vgn);
378
379 } else { /* voice */
380
381 if (curvce EQ vgn)
382 curinst = dat1;
383
384 s_inst[vgn] = dat1;
385 execins(vgn, dat1, 1);
386 }
387
388 break;
389
390 case PA_OSC: /* oscillator control */
391
392 if (vgt) { /* group */
393
394 for (i = 0; i < 12; i++)
395 if (vce2grp[i] EQ (1 + vgn))
396 pdoctl(i, osc, dat1, dat2);
397
398 } else { /* voice */
399
400 pdoctl(vgn, osc, dat1, dat2);
401 }
402
403 break;
404
405 case PA_WAVA: /* waveshape A select */
406
407 if (vgt) { /* group */
408
409 for (i = 0; i < 12; i++)
410 if (vce2grp[i] EQ (1 + vgn))
411 pdows(0, i, dat1);
412
413 } else { /* voice */
414
415 pdows(0, vgn, dat1);
416 }
417
418 break;
419
420 case PA_WAVB: /* waveshape B select */
421
422 if (vgt) { /* group */
423
424 for (i = 0; i < 12; i++)
425 if (vce2grp[i] EQ (1 + vgn))
426 pdows(1, i, dat1);
427
428 } else { /* voice */
429
430 pdows(1, vgn, dat1);
431 }
432
433 break;
434
435 case PA_CNFG: /* configuration select */
436
437 if (vgt) {
438
439 for (i = 0; i < 12; i++)
440 if (vce2grp[i] EQ (1 + vgn)) {
441
442 vbufs[i].idhcfg = dat1;
443 dosync(i);
444 }
445 } else {
446
447 vbufs[vgn].idhcfg = dat1;
448 dosync(vgn);
449 }
450
451 break;
452
453 case PA_LEVL: /* level */
454
455 if (vgt) { /* group */
456
457 for (i = 0; i < 12; i++)
458 if (vce2grp[i] EQ (1 + vgn))
459 pfpufn(i, 2, dat1, dat2);
460
461 } else { /* voice */
462
463 pfpufn(vgn, 2, dat1, dat2);
464 }
465
466 break;
467
468 case PA_INDX: /* index */
469
470 if (vgt) { /* group */
471
472 for (i = 0; i < 12; i++)
473 if (vce2grp[i] EQ (1 + vgn))
474 pfpufn(i, ind2par[osc], dat1, dat2);
475
476 } else { /* voice */
477
478 pfpufn(vgn, ind2par[osc], dat1, dat2);
479 }
480
481 break;
482
483 case PA_FREQ: /* frequency */
484
485 if (vgt) { /* group */
486
487 for (i = 0; i < 12; i++)
488 if (vce2grp[i] EQ (1 + vgn))
489 pfpufn(i, frq2par[osc], dat1, dat2);
490
491 } else { /* voice */
492
493 pfpufn(vgn, frq2par[osc], dat1, dat2);
494 }
495
496 break;
497
498 case PA_FILT: /* filter frequency */
499
500 if (vgt) { /* group */
501
502 for (i = 0; i < 12; i++)
503 if (vce2grp[i] EQ (1 + vgn))
504 pfpufn(i, 10, dat1, dat2);
505
506 } else { /* voice */
507
508 pfpufn(vgn, 10, dat1, dat2);
509 }
510
511 break;
512
513 case PA_FILQ: /* filter resonance */
514
515 if (vgt) { /* group */
516
517 for (i = 0; i < 12; i++)
518 if (vce2grp[i] EQ (1 + vgn))
519 pfpufn(i, 6, dat1, dat2);
520
521 } else { /* voice */
522
523 pfpufn(vgn, 6, dat1, dat2);
524 }
525
526 break;
527
528 case PA_LOCN: /* location */
529
530 if (vgt) { /* group */
531
532 for (i = 0; i < 12; i++)
533 if (vce2grp[i] EQ (1 + vgn))
534 pfpufn(i, 4, dat1, dat2);
535
536 } else { /* voice */
537
538 pfpufn(vgn, 4, dat1, dat2);
539 }
540
541 break;
542
543 case PA_DYNM: /* dynamics */
544
545 if (vgt) { /* group */
546
547 for (i = 0; i < 12; i++)
548 if (vce2grp[i] EQ (1 + vgn))
549 pfpufn(i, 8, dat1, dat2);
550
551 } else { /* voice */
552
553 pfpufn(vgn, 8, dat1, dat2);
554 }
555
556 break;
557
558 case PA_AUX: /* auxiliary control */
559
560 pfpufn(9, 0, dat1, dat2);
561 break;
562
563 case PA_RATE: /* phase shifter rate */
564
565 pfpufn(2, 0, dat1, dat2);
566 break;
567
568 case PA_INTN: /* phase shifter intensity */
569
570 pfpufn(1, 0, dat1, dat2);
571 break;
572
573 case PA_DPTH: /* phase shifter depth */
574
575 pfpufn(3, 0, dat1, dat2);
576 break;
577
578 case PA_VOUT: /* control voltage output */
579
580 pfpufn(cv2vce[suba], 0, dat1, dat2);
581 break;
582
583 }
584}
585
Note: See TracBrowser for help on using the repository browser.