source: buchla-68k/ram/wdfield.c@ a4bd34f

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

More volatile hardware accesses.

  • Property mode set to 100644
File size: 14.1 KB
Line 
1/*
2 =============================================================================
3 wdfield.c -- waveshape display field processing and cursor motion
4 Version 46 -- 1989-11-15 -- D.N. Lynx Crowe
5 =============================================================================
6*/
7
8#define DOUBLED 1 /* non-zero for doubled WS outputs */
9
10#include "ram.h"
11
12#define WCSCALE 32768L
13#define WCROUND 16384L
14
15#include "wdcurtb.h" /* int16_t wdcurtb[]; int16_t wdcurct[8][2]; */
16
17int16_t wxrate = 1; /* WS interpolate X movement increment */
18
19struct fet wd_fet1[] = {
20
21 {23, 10, 11, 0x0002, et_wavs, ef_wavs, rd_wavs, nd_wavs},
22 {23, 19, 20, 0x0102, et_wvce, ef_wvce, rd_wvce, nd_wvce},
23 {23, 34, 36, 0x0004, et_wpnt, ef_wpnt, rd_wpnt, nd_wpnt},
24 {23, 44, 48, 0x0104, et_woff, ef_woff, rd_woff, nd_woff},
25 {23, 61, 62, 0x0005, et_whar, ef_whar, rd_whar, nd_whar},
26
27 {24, 20, 20, 0x0302, et_wslt, ef_wslt, rd_wslt, nd_wslt},
28 {24, 57, 60, 0x0105, et_whrv, ef_whrv, rd_whrv, nd_whrv},
29
30 { 0, 0, 0, 0x0000, FN_NULL, FN_NULL, FN_NULL, FN_NULL}
31};
32
33int16_t wdbox[][8] = { /* display box parameters */
34
35 { 1, 1, 510, 307, WCFBX00, WCBBX00, 0, 1}, /* 0 */
36 { 1, 309, 510, 320, WCFBX01, WCBBX01, 22, 0}, /* 1 */
37 { 1, 322, 174, 348, WCFBX02, WCBBX02, 23, 1}, /* 2 */
38 {176, 322, 230, 348, WCFBX03, WCBBX03, 23, 23}, /* 3 */
39 {232, 322, 398, 348, WCFBX04, WCBBX04, 23, 30}, /* 4 */
40 {400, 322, 510, 348, WCFBX05, WCBBX05, 23, 51} /* 5 */
41};
42
43int8_t *wdbxlb0[] = { /* display box labels -- row 0 */
44
45 "", /* 0 */
46
47#ifndef PYCP
48 "\320\301 \320\303 \320\305 \320\307 \320\311 \
49\321\301 \321\303 \321\305 \321\307 \321\311 \
50\322\301 \322\303 \322\305 \322\307 \322\311 \323\301 ", /* 1 */
51#endif
52
53 "Waveshpe Voice", /* 2 */
54 "Store", /* 3 */
55 "Pnt Offst", /* 4 */
56 "Harmonic #" /* 5 */
57};
58
59int8_t *wdbxlb1[] = { /* display box labels -- row 1 */
60
61 "", /* 0 */
62 "", /* 1 */
63 "Instrument Slot", /* 2 */
64 "Fetch", /* 3 */
65 " Final", /* 4 */
66 "Value" /* 5 */
67};
68
69struct curpak wd_flds = {
70
71 stdctp1, /* curtype */
72 nokey, /* premove */
73 nokey, /* pstmove */
74 cxkstd, /* cx_key */
75 cykstd, /* cy_key */
76 wdcxupd, /* cx_upd */
77 wdcyupd, /* cy_upd */
78 wdykup, /* xy_up */
79 wdykdn, /* xy_dn */
80 wdxkey, /* x_key */
81 select, /* e_key */
82 stdmkey, /* m_key */
83 stddkey, /* d_key */
84 wdnfld, /* not_fld */
85 wd_fet1, /* curfet */
86 wdboxes, /* csbp */
87 crate1, /* cratex */
88 crate1, /* cratey */
89 CT_GRAF, /* cmtype */
90 WCURX, /* cxval */
91 WCURY /* cyval */
92};
93
94/*
95 =============================================================================
96 updfpu() -- update the FPU with a new waveshape
97 =============================================================================
98*/
99
100void updfpu(void)
101{
102 volatile uint16_t *wsp1;
103 int16_t *wsp2;
104
105 /* calculate instrument source and FPU destination pointers */
106
107 wsp1 = io_fpu + FPU_OWST + (curvce << 9) + (curwslt ? 0 : 0x0100) + 1;
108 wsp2 = curwslt ? vbufs[curvce].idhwvbf : vbufs[curvce].idhwvaf;
109
110 memcpyw(wsp1, wsp2, NUMWPNT);
111
112 /* make endpoints track */
113
114 *(wsp1 - 1) = *(wsp2 - 1); /* lowest point */
115 *(wsp1 + NUMWPNT) = *(wsp2 + NUMWPNT - 1); /* highest point */
116
117#if DOUBLED
118
119 /* do outputs again to get around hardware bug */
120
121 memcpyw(wsp1, wsp2, NUMWPNT);
122
123 *(wsp1 - 1) = *(wsp2 - 1); /* lowest point */
124 *(wsp1 + NUMWPNT) = *(wsp2 + NUMWPNT - 1); /* highest point */
125#endif
126
127 curwfnl = wsp2[curwpnt] >> 5; /* udpate final value */
128}
129
130/*
131 =============================================================================
132 wsupd() -- update the instrument definition and FPU for new WS offsets
133 =============================================================================
134*/
135
136void wsupd(void)
137{
138 register int16_t i;
139 register int16_t *wsp1, *wsp2;
140
141 /* update the offsets[] array from the instrument definition */
142
143 wsp2 = curwslt ? vbufs[curvce].idhwvbo : vbufs[curvce].idhwvao;
144
145 for (i = 0; i < NUMWPNT; i++)
146 offsets[i + 1] = wsp2[i] >> 5;
147
148 offsets[0] = offsets[1];
149
150 wscalc(); /* calculate the final values */
151
152 /* update the final values in the instrument definition */
153
154 wsp1 = curwslt ? vbufs[curvce].idhwvbf : vbufs[curvce].idhwvaf;
155
156 for (i = 0; i < NUMWPNT; i++)
157 wsp1[i] = wsbuf[1 + i] << 5;
158
159 updfpu();
160 wsnmod[curvce][curwslt] = TRUE; /* tag WS as modified */
161}
162
163/*
164 =============================================================================
165 whupd() -- update the FPU for new WS harmonics
166 =============================================================================
167*/
168
169void whupd(void)
170{
171 register int16_t i;
172 register int16_t *wsp1;
173
174 /* update the final values in the instrument definition */
175
176 wsp1 = curwslt ? vbufs[curvce].idhwvbf : vbufs[curvce].idhwvaf;
177
178 for (i = 0; i < NUMWPNT; i++)
179 wsp1[i] = wsbuf[i + 1] << 5;
180
181 updfpu(); /* update the FPU */
182 wsnmod[curvce][curwslt] = TRUE; /* tag WS as modified */
183}
184
185/*
186 =============================================================================
187 pntsup() -- update waveshape points with the cursor 'brush'
188 =============================================================================
189*/
190
191void pntsup(void)
192{
193 register struct instdef *ip;
194 int16_t *ov;
195 register int16_t i, j, k, tv, curdif;
196 int16_t cwnp, cwin;
197
198 ip = &vbufs[curvce]; /* instrument definition */
199
200 ov = curwslt ? &ip->idhwvbo /* offsets in definition */
201 : &ip->idhwvao;
202
203 cwnp = wdcurct[curwdth][0]; /* number of points effected */
204
205 cwin = wdcurct[curwdth][1]; /* table increment */
206
207 curdif = lstwoff - curwoff; /* calculate the difference */
208
209
210 for (i = 0 , k = 0; i < cwnp; i++ , k += cwin) {
211
212 if (i EQ 0) { /* first point */
213
214 ov[curwpnt] = curwoff << 5;
215
216 } else { /* subsequent points */
217
218 j = curwpnt + i; /* update point on the right */
219
220 if (j < NUMWPNT) { /* ... if it exists */
221
222 tv = (ov[j] >> 5) -
223 ((((long)curdif * wdcurtb[k])
224 + WCROUND) / WCSCALE);
225
226 if (tv GT 1023)
227 tv = 1023;
228 else if (tv LT -1023)
229 tv = -1023;
230
231 ov[j] = tv << 5;
232 }
233
234 j = curwpnt - i; /* update point on the left */
235
236 if (j GE 0) { /* ... if it exists */
237
238 tv = (ov[j] >> 5) -
239 ((((long)curdif * wdcurtb[k])
240 + WCROUND) / WCSCALE);
241
242 if (tv GT 1023)
243 tv = 1023;
244 else if (tv LT -1023)
245 tv = -1023;
246
247 ov[j] = tv << 5;
248 }
249 }
250 }
251
252 wsupd();
253}
254
255/*
256 =============================================================================
257 wdintp() -- interpolate between waveshape points
258 =============================================================================
259*/
260
261void wdintp(void)
262{
263 register struct instdef *ip;
264 register int16_t *ov;
265 register int16_t i, j, k, n;
266 register long t;
267 int16_t to, from;
268
269 to = curwpnt;
270 from = wplast;
271
272 ip = &vbufs[curvce];
273 ov = curwslt ? &ip->idhwvbo : &ip->idhwvao;
274
275 ov[curwpnt] = curwoff << 5; /* force current point value */
276
277 if (from > to) { /* make 'from' the leftmost point number */
278
279 i = from;
280 from = to;
281 to = i;
282 }
283
284 n = to - from; /* number of points */
285
286 if (n > 1) { /* have to have at least 1 point difference */
287
288 k = ov[from] >> 5;
289 t = ((long)((long)(ov[to] >> 5) - (long)k) << 16) / n;
290 j = 1 + from;
291 --n;
292
293 for (i = 0; i < n; i++)
294 ov[j++] = ((int16_t)((t * (1 + i)) >> 16) + k) << 5;
295 }
296
297 wplast = curwpnt;
298 wvlast = curwoff;
299
300 wsupd();
301}
302
303/*
304 =============================================================================
305 wdykdn() -- cursor y finger down processing
306 =============================================================================
307*/
308
309void wdykdn(void)
310{
311 if (wpntsv EQ 0)
312 return;
313
314 lstwpnt = curwpnt;
315 lstwoff = curwoff;
316}
317
318/*
319 =============================================================================
320 wdykup() -- cursor y finger up processing
321 =============================================================================
322*/
323
324void wdykup(void)
325{
326 if ((wpntsv EQ 0) OR (wdupdfl EQ FALSE))
327 return;
328
329 if (wpntsv EQ 1) { /* offsets */
330
331 if (curwdth EQ NUMWIDS)
332 wdintp(); /* interpolate mode */
333 else
334 pntsup(); /* brush mode */
335
336 } else { /* harmonics */
337
338 adj(curwhrm); /* adjust vknm[curwhrm][] */
339 wscalc(); /* recalculate the waveshape */
340 whupd(); /* update the FPU */
341 }
342
343 wdswin(0); /* display updated waveshape */
344 wdswin(2);
345 wdswin(4);
346
347 wdupdfl = FALSE;
348}
349
350/*
351 =============================================================================
352 wdcyupd() -- update cursor y location
353 =============================================================================
354*/
355
356void wdcyupd(void)
357{
358 register struct instdef *ip;
359 register int16_t *hv;
360 register int8_t wsgn;
361 int16_t wval;
362
363 ip = &vbufs[curvce];
364
365 switch (wpntsv) {
366
367 case 0: /* nothing selected -- just move cursor */
368
369 cyval += cyrate;
370
371 if (cyval GT (CYMAX - 1))
372 cyval = CYMAX - 1;
373 else if (cyval LT 1)
374 cyval = 1;
375
376 return;
377
378 case 1: /* offset selected */
379
380 curwoff -= cyrate;
381
382 if (curwoff GT 1023)
383 curwoff = 1023;
384 else if (curwoff LT -1023)
385 curwoff = -1023;
386
387 cyval = WPOFF - ((curwoff * WPSF1) / WPSF2);
388
389 if (curwoff < 0) {
390
391 wval = - curwoff;
392 wsgn = '-';
393
394 } else {
395
396 wval = curwoff;
397 wsgn = '+';
398 }
399
400 sprintf(bfs, "%c%04d", wsgn, wval);
401
402 if (v_regs[5] & 0x0180)
403 vbank(0);
404
405 vcputsv(waveob, 64, wdbox[4][4], wdbox[4][5], wdbox[4][6],
406 wdbox[4][7] + WOFF_OFF, bfs, 14);
407
408 wdupdfl = TRUE;
409 return;
410
411 case 2: /* harmonic selected */
412
413 hv = curwslt ? &ip->idhwvbh : &ip->idhwvah;
414
415 curwhrv = abs(hv[curwhrm]) - cyrate;
416
417 if (curwhrv > 100)
418 curwhrv = 100;
419 else if (curwhrv < 0)
420 curwhrv = 0;
421
422 curwhrv = (hv[curwhrm] < 0) ? -curwhrv : curwhrv;
423
424 hv[curwhrm] = curwhrv;
425 vmtab[curwhrm] = curwhrv;
426
427 if (curwhrv < 0) {
428
429 wval = -curwhrv;
430 wsgn = '-';
431
432 } else {
433
434 wval = curwhrv;
435 wsgn = '+';
436 }
437
438 if (v_regs[5] & 0x0180)
439 vbank(0);
440
441 sprintf(bfs, "%c%03d", wsgn, wval);
442
443 vcputsv(waveob, 64, wdbox[5][4], wdbox[5][5],
444 wdbox[5][6] + 1, wdbox[5][7] + WHRV_OFF, bfs, 14);
445
446 if (curwhrv < 0)
447 cyval = WBOFF - ((-curwhrv * WBSF1) / WBSF2);
448 else
449 cyval = WBOFF - ((curwhrv * WBSF1) / WBSF2);
450
451 wdupdfl = TRUE;
452 return;
453 }
454}
455
456/*
457 =============================================================================
458 wdcxupd() -- update cursor x location
459 =============================================================================
460*/
461
462void wdcxupd(void)
463{
464 switch (wpntsv) {
465
466 case 0: /* nothing selected - just move cursor */
467
468 cxval += cxrate;
469
470 if (cxval GT (CXMAX - 1))
471 cxval = CXMAX - 1;
472 else if (cxval LT 1)
473 cxval = 1;
474
475 return;
476
477 case 1: /* offset selected - maybe do interpolate move */
478
479 if (curwdth NE NUMWIDS)
480 return;
481
482 curwpnt += sign(cxrate, wxrate);
483
484 if (curwpnt GE NUMWPNT)
485 curwpnt = NUMWPNT - 1;
486 else if (curwpnt < 0)
487 curwpnt = 0;
488
489 cxval = (curwpnt << 1) + 2;
490
491 if (v_regs[5] & 0x0180)
492 vbank(0);
493
494 sprintf(bfs, "%03d", curwpnt);
495 vcputsv(waveob, 64, wdbox[4][4], wdbox[4][5],
496 wdbox[4][6], wdbox[4][7] + WPNT_OFF, bfs, 14);
497 }
498}
499
500/*
501 =============================================================================
502 wdnfld() -- process not-in-field key entry
503 =============================================================================
504*/
505
506int16_t wdnfld(int16_t k)
507{
508 register int16_t *hv;
509 register struct instdef *ip;
510
511 if (astat) {
512
513 if (whatbox()) {
514
515 ip = &vbufs[curvce];
516 hv = curwslt ? &ip->idhwvbh : &ip->idhwvah;
517
518 if (hitbox EQ 0) { /* waveshape area */
519
520 switch (wpntsv) {
521
522 case 0: /* nothing selected */
523
524 if (k EQ 8) { /* - */
525
526 if (--curwdth < 0)
527 curwdth = NUMWIDS;
528
529 wdswin(4);
530 return(SUCCESS);
531
532 } else if (k EQ 9) { /* + */
533
534 if (++curwdth > NUMWIDS)
535 curwdth = 0;
536
537 wdswin(4);
538 return(SUCCESS);
539 }
540
541 return(FAILURE);
542
543 case 1: /* offset selected */
544
545 if (k EQ 8) { /* - */
546
547 if (curwdth EQ NUMWIDS)
548 return(FAILURE);
549
550 if (--curwdth LT 0)
551 curwdth = NUMWIDS - 1;
552
553 wdswin(4);
554 return(SUCCESS);
555
556 } else if (k EQ 9) { /* + */
557
558 if (curwdth EQ NUMWIDS) {
559
560 wdintp();
561 wdswin(0);
562 wdswin(2);
563
564 } else if (++curwdth GE NUMWIDS)
565 curwdth = 0;
566
567 wdswin(4);
568 return(SUCCESS);
569 }
570
571 return(FAILURE);
572
573 case 2: /* harmonic selected */
574
575 if (k EQ 8) { /* - */
576
577 if (hv[curwhrm] > 0)
578 hv[curwhrm] = -hv[curwhrm];
579 else
580 return(FAILURE);
581
582 } else if (k EQ 9) { /* + */
583
584 if (hv[curwhrm] < 0)
585 hv[curwhrm] = -hv[curwhrm];
586 else
587 return(FAILURE);
588
589 } else {
590
591 return(FAILURE);
592 }
593
594 curwhrv = hv[curwhrm];
595 vmtab[curwhrm] = curwhrv;
596 adj(curwhrm);
597 wscalc();
598 whupd();
599 wdswin(0);
600 wdswin(4);
601 wdswin(5);
602 return(SUCCESS);
603 }
604
605 } else
606 return(FAILURE);
607
608 } else if (hitbox EQ 1) { /* harmonic legend */
609
610 if (k EQ 8) { /* - */
611
612 if (hv[curwhrm] > 0)
613 hv[curwhrm] = -hv[curwhrm];
614 else
615 return(FAILURE);
616
617 } else if (k EQ 9) { /* + */
618
619 if (hv[curwhrm] < 0)
620 hv[curwhrm] = -hv[curwhrm];
621 else
622 return(FAILURE);
623
624 } else {
625
626 return(FAILURE);
627 }
628
629 curwhrv = hv[curwhrm];
630 vmtab[curwhrm] = curwhrv;
631 adj(curwhrm);
632 wscalc();
633 whupd();
634 wdswin(0);
635 wdswin(4);
636 wdswin(5);
637 return(SUCCESS);
638 }
639
640 return(FAILURE);
641 }
642
643 return(FAILURE);
644}
645
646/*
647 =============================================================================
648 wdxkey() -- process X key
649 =============================================================================
650*/
651
652void wdxkey(void)
653{
654 if (NOT astat)
655 return; /* FAILURE */
656
657 stcrow = cyval / 14;
658 stccol = cxval >> 3;
659
660 if (stcrow EQ 23) {
661
662 if ((stccol GE 2) OR (stccol LE 8)) {
663
664 clrws();
665
666 } else if ((stccol GE 38) AND (stccol LE 42)) {
667
668 memsetw(curwslt ? vbufs[curvce].idhwvbo
669 : vbufs[curvce].idhwvbo,
670 0, NUMWPNT);
671
672 curwoff = 0;
673 wsupd();
674
675 } else if ((stccol GE 51) AND (stccol LE 58)) {
676
677 memsetw(vmtab, 0, NUMHARM);
678 curwhrv = 0;
679 wadj();
680 wscalc();
681 whupd();
682
683 } else {
684
685 return; /* FAILURE */
686 }
687
688 wsnmod[curvce][curwslt] = TRUE;
689 wwins();
690 return; /* SUCCESS */
691 }
692
693 return; /* FAILURE */
694}
695
696/*
697 =============================================================================
698 wdfield() -- setup field routines for the waveshape editor
699 =============================================================================
700*/
701
702void wdfield(void)
703{
704 curslim = 307;
705
706 curset(&wd_flds);
707}
Note: See TracBrowser for help on using the repository browser.