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

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

Fixed constant overflow warnings.

  • Property mode set to 100644
File size: 15.6 KB
Line 
1/*
2 =============================================================================
3 msm.c -- MIDAS-VII -- MIDI state machine
4 Version 75 -- 1988-11-02 -- D.N. Lynx Crowe
5
6 List with pr -e4 option to expand tabs to 4 spaces instead of 8.
7 =============================================================================
8*/
9
10#include "ram.h"
11
12/* initialized stuff */
13
14/* mpmap[] -- MIDI port to BIOS device table */
15
16int16_t mpmap[3] = {MC1_DEV, MC2_DEV, CON_DEV};
17
18/* msmnext[] -- MIDI state machine -- channel message next state table */
19
20int16_t msmnext[8] = {2, 2, 2, 2, 1, 1, 2, 0};
21
22/* msmcnxt[] -- MIDI state machine -- system message next state table */
23
24int16_t msmcnxt[8] = {0, 0, 2, 1, 0, 0, 0, 0};
25
26/* ctl2src -- controller to source table */
27
28int16_t ctl2src[] = {SM_VTMW, SM_LPBR, SM_CTL1, SM_PED1};
29
30/*
31 =============================================================================
32 msm() -- MIDI state machine
33 =============================================================================
34*/
35
36void msm(void)
37{
38 register int16_t miport;
39 register int16_t midiin;
40 register int16_t i;
41 register int16_t t1;
42 register int16_t t2;
43 register struct s_entry *ep;
44 int16_t j, nvel;
45 int32_t where;
46
47 for (miport = 0; miport < NMPORTS; miport++) { /* for each port ... */
48
49 while (BIOS(B_RDAV, mpmap[miport])) { /* anything there ? */
50
51 dsp_ok = FALSE; /* disallow display update */
52
53 midiin = 0x00FF & BIOS(B_GETC, mpmap[miport]); /* get input */
54
55 if (masens[miport]) /* update active sensing */
56 masens[miport] |= 0x0F;
57
58 switch (msmstv[miport]) { /* switch on state */
59
60 case 0: /* waiting for status */
61
62 if (0x0080 & midiin) { /* status */
63
64 michan = 0x000F & midiin;
65 mistat = 0x000F & (midiin >> 4);
66
67 if (midiin < 0x00F0) { /* channel */
68
69 msmstv[miport] = msmnext[mistat & 0x07];
70 mrstat[miport] = midiin;
71
72 } else if (midiin < 0x00F8) { /* common */
73
74 msmstv[miport] = msmcnxt[michan & 0x07];
75 mrstat[miport] = midiin;
76
77 } else { /* real-time */
78
79 switch (0x0007 & midiin) {
80
81 case 0: /* clock */
82
83 if (midiclk AND midigo)
84 if ((fc_val += 2) > 0x00FFFFFFL)
85 fc_val = 0x00FFFFFFL;
86
87 break;
88
89 case 2: /* start */
90
91 if ((clkctl EQ CK_MIDI) AND
92 (NOT midigo)) {
93
94 midigo = TRUE;
95
96 if (fc_val)
97 sc_goto(fc_val = 0L);
98
99 clkset(TRUE);
100 dsclk();
101 }
102
103 break;
104
105 case 3: /* continue */
106
107 if ((clkctl EQ CK_MIDI) AND
108 (NOT midigo)) {
109
110 midigo = TRUE;
111 clkset(TRUE);
112 dsclk();
113 }
114
115 break;
116
117 case 4: /* stop */
118
119 if ((clkctl EQ CK_MIDI) AND
120 midigo) {
121
122 midigo = FALSE;
123 clkset(FALSE);
124 dsclk();
125 }
126
127 break;
128
129 case 6: /* active sensing */
130
131 masens[miport] |= (int8_t)0x00FF;
132 break;
133
134 case 7: /* reset */
135
136 for (i = 0; i < NMPORTS; i++) {
137
138 mrstat[i] = 0;
139 msmstv[i] = 0;
140 masens[i] = 0;
141 }
142
143 break;
144 }
145 }
146 }
147
148 continue;
149
150 case 1: /* waiting for 1 data byte */
151
152 if (0x80 & midiin) { /* status */
153
154 michan = 0x0F & midiin;
155 mistat = 0x0F & (midiin >> 4);
156
157 if (midiin < 0x00F0) { /* channel */
158
159 msmstv[miport] = msmnext[mistat & 0x07];
160 mrstat[miport] = midiin;
161
162 } else if (midiin < 0x00F8) { /* common */
163
164 msmstv[miport] = msmcnxt[michan & 0x07];
165 mrstat[miport] = midiin;
166
167 } else { /* real-time */
168
169 switch (0x0007 & midiin) {
170
171 case 0: /* clock */
172
173 if (midiclk AND midigo)
174 if ((fc_val += 2) > 0x00FFFFFFL)
175 fc_val = 0x00FFFFFFL;
176
177 break;
178
179 case 2: /* start */
180
181 if ((clkctl EQ CK_MIDI) AND
182 (NOT midigo)) {
183
184 midigo = TRUE;
185
186 if (fc_val)
187 sc_goto(fc_val = 0L);
188
189 clkset(TRUE);
190 dsclk();
191 }
192
193 break;
194
195 case 3: /* continue */
196
197 if ((clkctl EQ CK_MIDI) AND
198 (NOT midigo)) {
199
200 midigo = TRUE;
201 clkset(TRUE);
202 dsclk();
203 }
204
205 break;
206
207 case 4: /* stop */
208
209 if ((clkctl EQ CK_MIDI) AND
210 midigo) {
211
212 midigo = FALSE;
213 clkset(FALSE);
214 dsclk();
215 }
216
217 break;
218
219 case 6: /* active sensing */
220
221 masens[miport] |= (int8_t)0x00FF;
222 break;
223
224 case 7: /* reset */
225
226 for (i = 0; i < NMPORTS; i++) {
227
228 mrstat[i] = 0;
229 msmstv[i] = 0;
230 masens[i] = 0;
231 }
232
233 break;
234 }
235 }
236
237 } else { /* data */
238
239 michan = 0x000F & mrstat[miport];
240 mistat = 0x000F & (mrstat[miport] >> 4);
241
242 if (mistat EQ 0x0C) {
243
244 /* program change */
245
246 if ((miport EQ 0) AND
247 ((michan + 1) EQ prgchan) AND
248 (midiin LT NASGS)) {
249
250 getasg(curasg = midiin);
251 mpcupd();
252 }
253
254 } else if (mistat EQ 0x0D) {
255
256 /* channel pressure */
257
258 mdb1 = SM_SCALE(midiin);
259 t1 = (miport << 11) | (michan << 7);
260 t2 = t1 + 128;
261
262 for (i = t1; i < t2; i++)
263 prstab[i] = mdb1;
264
265 for (i = 0; i < 12; i++) {
266
267 if ((grp2prt[i][0] EQ (miport + 1)) AND
268 (grp2prt[i][1] EQ (michan + 1))) {
269
270 if (newsv(i, SM_KPRS, mdb1)) {
271
272 if (recsw AND grpstat[i] AND
273 (2 EQ (ancmsw ? varmode[5][i] : grpmode[i]))) {
274
275 if (E_NULL NE (ep = e_alc(E_SIZE2))) {
276
277 ep->e_time = t_cur;
278 ep->e_type = EV_ANVL;
279 ep->e_data1 = (int8_t)(0x0050 | i);
280 ep->e_dn = (struct s_entry *)((int32_t)mdb1 << 16);
281 p_cur = e_ins(ep, ep_adj(p_cur, 0, t_cur))->e_fwd;
282 ctrsw = TRUE;
283 se_disp(ep, D_FWD, gdstbc, 1);
284 ctrsw = FALSE;
285 }
286
287 } else if ((angroup - 1) EQ i) {
288
289 dsanval(5);
290 }
291 }
292 }
293 }
294
295 } else if ((mistat EQ 0x0F) AND
296 (michan EQ 3) AND
297 (NOT midigo)) { /* song select */
298
299 if (midiin < N_SCORES) {
300
301 selscor(midiin);
302
303 if (ndisp EQ 2)
304 sdwins();
305 }
306
307 } else { /* error -- state mismatch */
308
309 msmstv[miport] = 0;
310 mrstat[miport] = 0;
311 }
312 }
313
314 continue;
315
316 case 2: /* waiting for 1st data byte */
317
318 if (0x80 & midiin) { /* status */
319
320 michan = 0x0F & midiin;
321 mistat = 0x0F & (midiin >> 4);
322
323 if (midiin < 0x00F0) { /* channel */
324
325 msmstv[miport] = msmnext[mistat & 0x07];
326 mrstat[miport] = midiin;
327
328 } else if (midiin < 0x00F8) { /* common */
329
330 msmstv[miport] = msmcnxt[michan & 0x07];
331 mrstat[miport] = midiin;
332
333 } else { /* real-time */
334
335 switch (0x0007 & midiin) {
336
337 case 0: /* clock */
338
339 if (midiclk AND midigo)
340 if ((fc_val += 2) > 0x00FFFFFFL)
341 fc_val = 0x00FFFFFFL;
342
343 break;
344
345 case 2: /* start */
346
347 if ((clkctl EQ CK_MIDI) AND
348 (NOT midigo)) {
349
350 midigo = TRUE;
351
352 if (fc_val)
353 sc_goto(fc_val = 0L);
354
355 clkset(TRUE);
356 dsclk();
357 }
358
359 break;
360
361 case 3: /* continue */
362
363 if ((clkctl EQ CK_MIDI) AND
364 (NOT midigo)) {
365
366 midigo = TRUE;
367 clkset(TRUE);
368 dsclk();
369 }
370
371 break;
372
373 case 4: /* stop */
374
375 if ((clkctl EQ CK_MIDI) AND
376 midigo) {
377
378 midigo = FALSE;
379 clkset(FALSE);
380 dsclk();
381 }
382
383 break;
384
385 case 6: /* active sensing */
386
387 masens[miport] |= (int8_t)0x00FF;
388 break;
389
390 case 7: /* reset */
391
392 for (i = 0; i < NMPORTS; i++) {
393
394 mrstat[i] = 0;
395 msmstv[i] = 0;
396 masens[i] = 0;
397 }
398
399 break;
400 }
401 }
402
403 } else { /* data */
404
405 mdbyte[miport] = midiin;
406 msmstv[miport] = 3;
407 }
408
409 continue;
410
411 case 3: /* waiting for 2nd data byte */
412
413 if (0x80 & midiin) { /* status */
414
415 michan = 0x0F & midiin;
416 mistat = 0x0F & (midiin >> 4);
417
418 if (midiin < 0x00F0) { /* channel */
419
420 msmstv[miport] = msmnext[mistat & 0x07];
421 mrstat[miport] = midiin;
422
423 } else if (midiin < 0x00F8) { /* common */
424
425 msmstv[miport] = msmcnxt[michan & 0x07];
426 mrstat[miport] = midiin;
427
428 } else { /* real-time */
429
430 switch (0x0007 & midiin) {
431
432 case 0: /* clock */
433
434 if (midiclk AND midigo)
435 if ((fc_val += 2) > 0x00FFFFFFL)
436 fc_val = 0x00FFFFFFL;
437
438 break;
439
440 case 2: /* start */
441
442 if ((clkctl EQ CK_MIDI) AND
443 (NOT midigo)) {
444
445 midigo = TRUE;
446
447 if (fc_val)
448 sc_goto(fc_val = 0L);
449
450 clkset(TRUE);
451 dsclk();
452 }
453
454 break;
455
456 case 3: /* continue */
457
458 if ((clkctl EQ CK_MIDI) AND
459 (NOT midigo)) {
460
461 midigo = TRUE;
462 clkset(TRUE);
463 dsclk();
464 }
465
466 break;
467
468 case 4: /* stop */
469
470 if ((clkctl EQ CK_MIDI) AND
471 midigo) {
472
473 midigo = FALSE;
474 clkset(FALSE);
475 dsclk();
476 }
477
478 break;
479
480 case 6: /* active sensing */
481
482 masens[miport] |= (int8_t)0x00FF;
483 break;
484
485 case 7: /* reset */
486
487 for (i = 0; i < NMPORTS; i++) {
488
489 mrstat[i] = 0;
490 msmstv[i] = 0;
491 masens[i] = 0;
492 }
493
494 break;
495 }
496 }
497
498 } else { /* data */
499
500 michan = 0x0F & mrstat[miport];
501 mistat = 0x0F & (mrstat[miport] >> 4);
502 mdb1 = mdbyte[miport];
503 mdb2 = midiin;
504 msmstv[miport] = 2;
505
506 switch (mistat) { /* switch on status */
507
508 case 9: /* note on */
509
510 if (mdb2) {
511
512 t1 = (miport << 11) + (michan << 7) + mdb1;
513 trgtab[t1] |= mpsust[(miport << 4) + michan] | M_KSTATE;
514 veltab[t1] = nvel = SM_SCALE(mdb2);
515 prstab[t1] = 0;
516
517 stmproc((uint16_t)t1); /* process as a patch stimulus */
518
519 if (editsw) { /* edit mode */
520
521 execkey(t1, tuntab[mdb1], curvce, 0);
522 break;
523 }
524
525 if (miport) { /* port 1 or 2 */
526
527 for (i = 0; i < 12; i++)
528 if ((grp2prt[i][0] EQ (miport + 1)) AND
529 (grp2prt[i][1] EQ (michan + 1))) {
530
531 asgvce(i, miport, michan, mdb1, nvel);
532 ne_bgn(i, mdb1, nvel);
533 }
534
535 } else { /* port 0 */
536
537 t2 = ((mdb1 < 21) OR (mdb1 > 108)) ?
538 0 : key2grp[mdb1 - 21];
539
540 for (i = 0; i < 12; i++)
541 if ((t2 & (0x0001 << i)) AND
542 (grp2prt[i][1] EQ (michan + 1))) {
543
544 asgvce(i, miport, michan, mdb1, nvel);
545 ne_bgn(i, mdb1, nvel);
546 }
547 }
548
549 break;
550 }
551
552 case 8: /* note off */
553
554 t1 = (miport << 11) + (michan << 7) + mdb1;
555 trgtab[t1] &= ~M_KSTATE;
556
557 if (0 EQ trgtab[t1]) {
558
559 for (i = 0; i < 12; i++) {
560
561 if (vce2trg[i] EQ t1) {
562
563 vce2trg[i] = -1;
564 procpfl(t1);
565 }
566
567 if ((grp2prt[i][0] EQ (miport + 1)) AND
568 (grp2prt[i][1] EQ (michan + 1)))
569 ne_end(t1, i);
570 }
571
572 stmproc((uint16_t)0x8000 | (uint16_t)t1); /* process as a patch stimulus */
573 }
574
575 break;
576
577 case 10: /* poly pressure */
578
579 t1 = (miport << 11) + (michan << 7) + mdb1;
580 t2 = SM_SCALE(mdb2);
581 prstab[t1] = t2;
582
583 for (i = 0; i < 12; i++)
584 if ((grp2prt[i][0] EQ (miport + 1)) AND
585 (grp2prt[i][1] EQ (michan + 1)))
586 newpps(t1, i, SM_KPRS, t2);
587
588 break;
589
590 case 11: /* control change */
591
592 mctlval[(miport << 11) + (michan << 7) + mdb1] = mdb2;
593
594 if (mdb1 EQ MIDISUS) {
595
596 /* sustain changed */
597
598 t1 = (miport << 11) | (michan << 7);
599 t2 = t1 + 128;
600
601 if (mdb2 GT MSW_ON) { /* switch on */
602
603 mpsust[(miport << 4) + michan] = M_CHNSUS;
604
605 for (i = t1; i < t2; i++)
606 if (trgtab[i])
607 trgtab[i] |= M_CHNSUS;
608
609 } else if (mdb2 LT MSW_OFF) { /* switch off */
610
611 mpsust[(miport << 4) + michan] = 0;
612
613 for (i = t1; i < t2; i++) {
614
615 if (trgtab[i]) {
616
617 trgtab[i] &= ~M_CHNSUS;
618
619 if (0 EQ trgtab[i]) {
620
621 for (t1 = 0; t1 < 12; t1++) {
622
623 if (vce2trg[t1] EQ i) {
624
625 vce2trg[t1] = -1;
626 procpfl(i);
627 }
628
629 if ((grp2prt[t1][0] EQ (miport + 1)) AND
630 (grp2prt[t1][1] EQ (michan + 1)))
631 ne_end(i, t1);
632 }
633 }
634 }
635 }
636 }
637
638 } else if (mdb1 EQ MIDIHLD) {
639
640 /* hold changed */
641
642 t1 = (miport << 11) | (michan << 7);
643 t2 = t1 + 128;
644
645 if (mdb2 GT MSW_ON) { /* switch on */
646
647 for (i = t1; i < t2; i++)
648 if (trgtab[i] & M_KSTATE) {
649
650 for (t1 = 0; t1 < 12; t1++)
651 if ((vce2trg[t1] & ~(MKEYHELD << 8)) EQ i)
652 vce2trg[t1] |= (M_CHNHLD << 8);
653 }
654
655 } else if (mdb2 LT MSW_OFF) { /* switch off */
656
657 for (i = 0; i <12; i++) {
658
659 if (vce2trg[i] NE -1) {
660
661 vce2trg[i] &= ~(M_CHNHLD << 8);
662
663 if (0 EQ (vce2trg[i] & (MKEYHELD << 8))) {
664
665 t1 = vce2trg[i];
666
667 if (0 EQ trgtab[t1]) {
668
669 vce2trg[i] = -1;
670 procpfl(t1);
671 }
672 }
673 }
674 }
675 }
676
677 } else { /* other controllers */
678
679 t1 = (miport << 11) | (michan << 7) | mdb1;
680 t2 = SM_SCALE(mdb2);
681 mctlval[t1] = t2;
682
683 for (j = 0; j < 4; j++) {
684
685 if ((mctlnum[j] & 0x00FF) EQ mdb1) {
686
687 i = ctl2src[j];
688
689 for (t1 = 0; t1 < 12; t1++) {
690
691 if ((mctlnum[j] & CTAG1) OR
692 ((grp2prt[t1][0] EQ (miport + 1)) AND
693 (grp2prt[t1][1] EQ (michan + 1)))) {
694
695 if (newsv(t1, i, t2)) {
696
697 if (recsw AND grpstat[t1] AND
698 (2 EQ (ancmsw ? varmode[src2var[i]][t1] : grpmode[t1]))) {
699
700 if (E_NULL NE (ep = e_alc(E_SIZE2))) {
701
702 ep->e_time = t_cur;
703 ep->e_type = EV_ANVL;
704 ep->e_data1 = (int8_t)((src2var[i] << 4) | t1);
705 ep->e_dn = (struct s_entry *)((int32_t)t2 << 16);
706 p_cur = e_ins(ep, ep_adj(p_cur, 0, t_cur))->e_fwd;
707 ctrsw = TRUE;
708 se_disp(ep, D_FWD, gdstbc, 1);
709 ctrsw = FALSE;
710 }
711
712 } else if ((angroup - 1) EQ t1) {
713
714 dsanval(src2var[i]);
715 }
716 }
717 }
718 }
719 }
720 }
721 }
722
723 break;
724
725 case 14: /* pitch bend */
726
727 t1 = (miport << 4) | michan;
728 t2 = ((mdb2 << 9) | (mdb1 << 2)) ^ (int16_t)0x8000;
729 mpbend[t1] = t2;
730
731 for (i = 0; i < 12; i++) {
732
733 if ((grp2prt[i][0] EQ (miport + 1)) AND
734 (grp2prt[i][1] EQ (michan + 1))) {
735
736 if (newsv(i, SM_HTPW, t2)) {
737
738 if (recsw AND grpstat[i] AND
739 (2 EQ (ancmsw ? varmode[0][i] : grpmode[i]))) {
740
741 if (E_NULL NE (ep = e_alc(E_SIZE2))) {
742
743 ep->e_time = t_cur;
744 ep->e_type = EV_ANVL;
745 ep->e_data1 = (int8_t)i;
746 ep->e_dn = (struct s_entry *)((int32_t)t2 << 16);
747 p_cur = e_ins(ep, ep_adj(p_cur, 0, t_cur))->e_fwd;
748 ctrsw = TRUE;
749 se_disp(ep, D_FWD, gdstbc, 1);
750 ctrsw = FALSE;
751 }
752
753 } else if ((angroup - 1) EQ i) {
754
755 dsanval(0);
756 }
757 }
758 }
759 }
760
761 break;
762
763 case 15: /* common */
764
765 if (michan EQ 2) { /* song position */
766
767 if ((clkctl EQ CK_MIDI) AND
768 (NOT midigo)) {
769
770 where = 12 * ((mdb1 << 7) | mdb2);
771
772 if (fc_val NE where)
773 sc_goto(fc_val = where);
774 }
775
776 break;
777
778 } else { /* bad running status */
779
780 msmstv[miport] = 0;
781 mrstat[miport] = 0;
782 break;
783 }
784
785 default: /* error -- bad status */
786
787 msmstv[miport] = 0;
788 mrstat[miport] = 0;
789 break;
790
791 } /* end switch (on status) */
792
793 } /* end if (status) */
794
795 continue;
796
797 default: /* error -- bad state */
798
799 msmstv[miport] = 0;
800 mrstat[miport] = 0;
801 break;
802
803 } /* end switch (on state) */
804 } /* end while (data available) */
805 } /* end for (each port) */
806}
807
Note: See TracBrowser for help on using the repository browser.