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

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

More volatile hardware accesses.

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