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

Last change on this file was eee74cd, checked in by Thomas Lopatic <thomas@…>, 6 years ago

Fixed mixed-signedness comparisons.

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