source: buchla-68k/ram/uslice.c@ f4fbee9

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

Unix line breaks.

  • Property mode set to 100644
File size: 16.7 KB
Line 
1/*
2 =============================================================================
3 uslice.c -- update score display slice
4 Version 32 -- 1988-09-28 -- D.N. Lynx Crowe
5 =============================================================================
6*/
7
8#undef DEBUGGER
9
10#define DEBUGIT 0
11
12#include "debug.h"
13
14#include "stddefs.h"
15#include "slice.h"
16#include "hwdefs.h"
17#include "score.h"
18#include "vsdd.h"
19#include "graphdef.h"
20
21#include "midas.h"
22#include "scdsp.h"
23#include "scfns.h"
24
25#define BARCOLOR 0x3333
26
27/* variables defined elsewhere */
28
29#if DEBUGIT
30extern short debugsw;
31#endif
32
33extern unsigned scrl;
34
35extern short sbase;
36extern short sd;
37extern short soffset;
38
39extern unsigned *consl;
40extern unsigned *cursl;
41extern unsigned *nxtsl;
42extern unsigned *prvsl;
43extern unsigned *saddr;
44
45extern unsigned slices[];
46
47extern short gtctab[12]; /* group to color table */
48
49extern struct gdsel *gdfsep; /* gdsel freechain pointer */
50
51extern struct gdsel *gdstbc[NGDSEL]; /* group status list heads */
52extern struct gdsel *gdstbn[NGDSEL]; /* group status list heads */
53extern struct gdsel *gdstbp[NGDSEL]; /* group status list heads */
54
55extern struct gdsel gdfsl[MAXFSL]; /* gdsel pool */
56
57/*
58
59*/
60
61/* initialized data */
62
63short lintab1[] = { /* note top line table */
64
65 205, 205, 201, 197, 197, 193, 193, 189, 185, 185, 181, 181,
66 177, 177, 173, 169, 169, 165, 165, 161, 157, 157, 153, 153,
67 149, 149, 145, 141, 141, 137, 137, 133, 129, 129, 125, 125,
68 121, 121, 117, 113, 113, 109, 109, 105, 101, 101, 97, 97,
69 93, 93, 89, 85, 85, 81, 81, 77, 73, 73, 69, 69,
70 65, 65, 61, 57, 57, 53, 53, 49, 45, 45, 41, 41,
71 37, 37, 33, 29, 29, 25, 25, 21, 17, 17, 13, 13,
72 9, 9, 5, 1
73};
74
75short lintab2[] = { /* note top line table - N_FLAT */
76
77 205, 201, 201, 197, 193, 193, 189, 189, 185, 181, 181, 177,
78 177, 173, 173, 169, 165, 165, 161, 161, 157, 153, 153, 149,
79 149, 145, 145, 141, 137, 137, 133, 133, 129, 125, 125, 121,
80 121, 117, 117, 113, 109, 109, 105, 105, 101, 97, 97, 93,
81 93, 89, 89, 85, 81, 81, 77, 77, 73, 69, 69, 65,
82 65, 61, 61, 57, 53, 53, 49, 49, 45, 41, 41, 37,
83 37, 33, 33, 29, 25, 25, 21, 21, 17, 13, 13, 9,
84 9, 5, 5, 1
85};
86
87short nttab1[] = { /* forward code transition table */
88
89 0, /* 0 */
90 2, /* 1 */
91 3, /* 2 */
92 3, /* 3 */
93 5, /* 4 */
94 3, /* 5 */
95 0 /* 6 */
96};
97
98short nttab2[] = { /* backward code transition table */
99
100 0, /* 0 */
101 0, /* 1 */
102 1, /* 2 */
103 3, /* 3 */
104 0, /* 4 */
105 4, /* 5 */
106 0 /* 6 */
107};
108
109/*
110
111*/
112
113short pxtbl[][4] = { /* pixel mask table for notes */
114
115 { 0x0000, 0x0000, 0x0000, 0 }, /* 0 */
116 { 0x0000, 0x0000, 0xFFFF, 0 }, /* 1 */
117 { 0x0000, 0xFFFF, 0xFFFF, 0 }, /* 2 */
118 { 0xFFFF, 0xFFFF, 0xFFFF, 0 }, /* 3 */
119 { 0xFFFF, 0x0000, 0x0000, 0 }, /* 4 */
120 { 0xFFFF, 0xFFFF, 0x0000, 0 }, /* 5 */
121 { 0xFFFF, 0xFFFF, 0xFFFF, 0 } /* 6 */
122};
123
124short epxtbl[][16] = { /* pixel mask table for events */
125
126 { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, /* 0 */
127 0xFFFF, 0x0000, 0x0000, 0x0000,
128 0x0000, 0x0000, 0x0000, 0x0000,
129 0, 0, 0, 0 },
130
131 { 0x0000, 0x0000, 0x0000, 0x0000, /* 1 */
132 0x0000, 0xFFFF, 0xFFFF, 0x0000,
133 0x0000, 0x0000, 0x0000, 0x0000,
134 0, 0, 0, 0 },
135
136 { 0x0000, 0x0000, 0x0000, 0x0000, /* 2 */
137 0x0000, 0x0000, 0x0000, 0xFFFF,
138 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
139 0, 0, 0, 0 },
140
141 { 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, /* 3 */
142 0x0000, 0x0000, 0x0000, 0x0000,
143 0x0000, 0x0000, 0x0000, 0x0000,
144 0, 0, 0, 0 },
145
146 { 0x0000, 0x0000, 0x0000, 0xFFFF, /* 4 */
147 0xFFFF, 0xFFFF, 0x0000, 0x0000,
148 0x0000, 0x0000, 0x0000, 0x0000,
149 0, 0, 0, 0 },
150
151 { 0x0000, 0x0000, 0x0000, 0x0000, /* 5 */
152 0x0000, 0x0000, 0xFFFF, 0xFFFF,
153 0xFFFF, 0x0000, 0x0000, 0x0000,
154 0, 0, 0, 0 },
155
156 { 0x0000, 0x0000, 0x0000, 0x0000, /* 6 */
157 0x0000, 0x0000, 0x0000, 0x0000,
158 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,
159 0, 0, 0, 0 }
160};
161
162/*
163
164*/
165
166/*
167 =============================================================================
168 uslice(slice, mask1, mask2, gdstb)
169
170 Updates 'slice[]' using 'mask1' and 'mask2' for the pixel mask
171 and the slice mask, respectively, and 'gdstb[]' for the group table.
172
173 Note transitions are based on the value of global variable 'sd',
174 which is zero for forward, and non-zero for backward scrolling.
175
176 Returns count of active groups and event priority levels.
177
178 Note colors come from 'gtctab[]'.
179
180 This code must be very fast or the display bogs down the system.
181 =============================================================================
182*/
183
184short
185uslice(slice, mask1, mask2, gdstb)
186unsigned *slice;
187register unsigned mask1, mask2;
188struct gdsel *gdstb[];
189{
190 register unsigned *pxptr, *slptr;
191 register struct gdsel *gdsep;
192 register unsigned i, ncolor, w;
193 unsigned *ncptr, *nctabp;
194 struct gdsel **gdstp, *gdprv, *gdnxt;
195 short wrote;
196 short *lintab;
197
198 DB_ENTR("uslice()");
199
200 /* initialize note color, note control, and group control pointers */
201
202 gdstp = gdstb; /* group control table */
203 nctabp = sd ? nttab2 : nttab1; /* note transition table */
204 ncptr = gtctab; /* group to color table */
205 wrote = 0; /* reset count of active groups */
206
207 lintab = (ac_code EQ N_SHARP) ? lintab1 : lintab2; /* line table */
208
209 if (gdstb[NGDSEL - 1]) { /* check for a bar marker */
210
211 slptr = slice; /* point at the slice */
212 ncolor = mask1 & BARCOLOR; /* setup bar write variable */
213
214 for (i = 211; i--; ) /* draw the bar */
215 *slptr++ = (*slptr & mask2) | ncolor;
216
217 gdstb[NGDSEL - 1] = (struct gdsel *)NULL; /* clear flag */
218 }
219
220/*
221
222*/
223
224 for (i = 0; i < 12; i++) { /* scan the group control table ... */
225
226 ncolor = mask1 & *ncptr++; /* get note color mask */
227 gdprv = (struct gdsel *)gdstp; /* setup previous pointer */
228 gdsep = *gdstp++; /* setup current pointer */
229
230 if (gdsep) { /* ... process each active group ... */
231
232 ++wrote; /* indicate slice was updated */
233
234 do { /* ... for each note played by the group ... */
235
236 /* setup slice and pixel pointers */
237
238 slptr = slice + lintab[gdsep->note];
239 pxptr = &pxtbl[gdsep->code][0];
240
241 /* update the slice */
242
243 *slptr++ = (*slptr & mask2) | (*pxptr++ & ncolor);
244 *slptr++ = (*slptr & mask2) | (*pxptr++ & ncolor);
245 *slptr = (*slptr & mask2) | (*pxptr++ & ncolor);
246
247 gdnxt = gdsep->next; /* set next pointer */
248
249 /* update and check update note status code */
250
251 if (0 EQ (gdsep->code = nctabp[gdsep->code])) {
252
253 /* if it's zero, delete the element */
254
255 gdprv->next = gdnxt;
256 gdsep->next = gdfsep;
257 gdfsep = gdsep;
258
259 } else
260 gdprv = gdsep;
261
262 gdsep = gdnxt; /* set pointer for next pass */
263
264 } while (gdsep);
265 }
266 }
267
268/*
269
270*/
271 for (; i < (NGDSEL - 1); i++) {
272
273 gdprv = (struct gdsel *)gdstp; /* setup previous pointer */
274 gdsep = *gdstp++; /* setup current pointer */
275
276 if (gdsep) { /* ... process each active event priority ... */
277
278 ++wrote; /* indicate slice was updated */
279
280 do { /* ... for each event of this priority ... */
281
282 /* setup slice and pixel pointers */
283
284 slptr = slice + 212;
285 pxptr = &epxtbl[gdsep->code][0];
286
287 /* get event color */
288
289 ncolor = mask1 & gdsep->note;
290
291 /* update the slice */
292
293 if (w = *pxptr++) /* 212 */
294 *slptr = (*slptr & mask2) | (w & ncolor);
295
296 ++slptr;
297
298 if (w = *pxptr++) /* 213 */
299 *slptr = (*slptr & mask2) | (w & ncolor);
300
301 ++slptr;
302
303 if (w = *pxptr++) /* 214 */
304 *slptr = (*slptr & mask2) | (w & ncolor);
305
306 ++slptr;
307
308 if (w = *pxptr++) /* 215 */
309 *slptr = (*slptr & mask2) | (w & ncolor);
310
311 ++slptr;
312
313 if (w = *pxptr++) /* 216 */
314 *slptr = (*slptr & mask2) | (w & ncolor);
315
316 ++slptr;
317
318 if (w = *pxptr++) /* 217 */
319 *slptr = (*slptr & mask2) | (w & ncolor);
320
321 ++slptr;
322
323 if (w = *pxptr++) /* 218 */
324 *slptr = (*slptr & mask2) | (w & ncolor);
325
326 ++slptr;
327
328 if (w = *pxptr++) /* 219 */
329 *slptr = (*slptr & mask2) | (w & ncolor);
330
331 ++slptr;
332
333 if (w = *pxptr++) /* 220 */
334 *slptr = (*slptr & mask2) | (w & ncolor);
335
336 ++slptr;
337
338 if (w = *pxptr++) /* 221 */
339 *slptr = (*slptr & mask2) | (w & ncolor);
340
341 ++slptr;
342
343 if (w = *pxptr++) /* 222 */
344 *slptr = (*slptr & mask2) | (w & ncolor);
345
346 ++slptr;
347
348 if (w = *pxptr) /* 223 */
349 *slptr = (*slptr & mask2) | (w & ncolor);
350
351 gdnxt = gdsep->next; /* set next pointer */
352 gdprv->next = gdnxt; /* delete the element */
353 gdsep->next = gdfsep;
354 gdfsep = gdsep;
355 gdsep = gdnxt; /* set pointer for next pass */
356
357 } while (gdsep);
358 }
359 }
360
361 DB_EXIT(wrote ? "uslice - slice written" : "uslice - no write");
362
363 return(wrote);
364}
365
366/*
367
368*/
369
370/*
371 =============================================================================
372 rslice(gdstb)
373
374 Reverses the slice codes in 'gdstb' based the value of sd,
375 which is zero for forward, and non-zero for backward scrolling.
376 =============================================================================
377*/
378
379rslice(gdstb)
380struct gdsel *gdstb[];
381{
382 register struct gdsel *gdsep;
383 register struct gdsel **gdstp;
384 register unsigned *nctabp;
385 register unsigned i, nc;
386 struct gdsel *gdprv, *gdnxt;
387
388 DB_ENTR("rslice");
389
390#if DEBUGIT
391 if (debugsw)
392 printf("\nrslice($%lX): sd = %s\n", gdstb, sd ? "BAK" : "FWD");
393#endif
394
395 /* initialize note control and group control pointers */
396
397 nctabp = sd ? nttab2 : nttab1; /* note control table pointer */
398 gdstp = gdstb; /* group control table pointer */
399
400/*
401
402*/
403 /* reverse note codes */
404
405 for (i = 0; i < 12; i++) { /* scan the group control table ... */
406
407 gdprv = (struct gdsel *)gdstp; /* setup previous pointer */
408 gdsep = *gdstp++; /* setup current pointer */
409
410 if (gdsep) { /* ... process each active group ... */
411
412 do { /* ... for each note played by the group ... */
413
414 gdnxt = gdsep->next; /* set next pointer */
415
416 /* update and check update note status code */
417
418 if (0 EQ (gdsep->code = nctabp[nc = gdsep->code])) {
419
420#if DEBUGIT
421 if (debugsw)
422 printf("rslice: note %d - %d -> %d\n",
423 gdsep->note, nc, gdsep->code);
424#endif
425
426 /* if it's zero, delete the element */
427
428 gdprv->next = gdnxt;
429 gdsep->next = gdfsep;
430 gdfsep = gdsep;
431
432 } else {
433
434#if DEBUGIT
435 if (debugsw)
436 printf("rslice: note %d - %d -> %d\n",
437 gdsep->note, nc, gdsep->code);
438#endif
439
440 gdprv = gdsep;
441 }
442
443 gdsep = gdnxt; /* set pointer for next pass */
444
445 } while (gdsep);
446 }
447 }
448
449/*
450
451*/
452 /* delete event codes */
453
454 for (; i < NGDSEL - 1; i++) {
455
456 gdprv = (struct gdsel *)gdstp; /* setup previous pointer */
457 gdsep = *gdstp++; /* setup current pointer */
458
459 if (gdsep) { /* ... process each active event priority ... */
460
461 do { /* ... for each event of this priority ... */
462
463 gdnxt = gdsep->next; /* set next pointer */
464 gdprv->next = gdnxt; /* delete the element */
465 gdsep->next = gdfsep;
466 gdfsep = gdsep;
467 gdsep = gdnxt; /* set pointer for next pass */
468
469 } while (gdsep);
470 }
471 }
472
473 gdstb[NGDSEL - 1] = (struct gdsel *)NULL; /* clear bar flag */
474
475 DB_EXIT("rslice");
476}
477
478/*
479
480*/
481
482/*
483 =============================================================================
484 cslice(slice, mask1, mask2, gdstb)
485
486 Updates 'slice[]' using 'mask1' and 'mask2' for the pixel mask
487 and the slice mask, respectively, using 'gdstb[]' as the group table.
488
489 Differs from uslice() in that no note gdstb events are deleted.
490 Used for center slice updates.
491
492 Note transitions are based on the value of global variable 'sd',
493 which is zero for forward, and non-zero for backward scrolling.
494
495 Returns count of active groups and event priority levels.
496
497 Note colors come from 'gtctab[]'.
498
499 This code has to be very fast.
500 =============================================================================
501*/
502
503short
504cslice(slice, mask1, mask2, gdstb)
505unsigned *slice;
506register unsigned mask1, mask2;
507struct gdsel *gdstb[];
508{
509 register unsigned *pxptr, *slptr;
510 register struct gdsel *gdsep;
511 register unsigned i, ncolor, w;
512 unsigned *ncptr, *nctabp;
513 struct gdsel **gdstp, *gdprv, *gdnxt;
514 short wrote;
515 short *lintab;
516
517 DB_ENTR("cslice()");
518
519 /* initialize note color, note control, and group control pointers */
520
521 gdstp = gdstb; /* group control table */
522 nctabp = sd ? nttab2 : nttab1; /* note transition table */
523 ncptr = gtctab; /* group to color table */
524 wrote = 0; /* reset count of active groups */
525
526 lintab = (ac_code EQ N_SHARP) ? lintab1 : lintab2; /* line table */
527
528 if (gdstb[NGDSEL - 1]) { /* check for a bar marker */
529
530 slptr = slice; /* point at the slice */
531 ncolor = mask1 & BARCOLOR; /* setup bar write variable */
532
533 for (i = 211; i--; ) /* draw the bar */
534 *slptr++ = (*slptr & mask2) | ncolor;
535
536 gdstb[NGDSEL - 1] = (struct gdsel *)NULL; /* clear flag */
537 }
538
539/*
540
541*/
542
543 for (i = 0; i < 12; i++) { /* scan the group control table ... */
544
545 ncolor = *ncptr++; /* get note color */
546 gdprv = (struct gdsel *)gdstp; /* setup previous pointer */
547 gdsep = *gdstp++; /* setup current pointer */
548
549 if (gdsep) { /* ... process each active group ... */
550
551#ifdef DEBUGGER
552 sprintf(DBvar, "cslice - g=%d gdsep=$%lX", i, gdsep); DB_CMNT(DBvar);
553#endif
554 ++wrote; /* indicate slice was updated */
555
556 do { /* ... for each note played by the group ... */
557
558 /* setup slice and pixel pointers */
559
560 slptr = slice + lintab[gdsep->note];
561 pxptr = &pxtbl[gdsep->code][0];
562
563 /* update the slice */
564
565 *slptr++ = (*slptr & mask2) | (*pxptr++ & ncolor);
566 *slptr++ = (*slptr & mask2) | (*pxptr++ & ncolor);
567 *slptr = (*slptr & mask2) | (*pxptr++ & ncolor);
568
569 gdnxt = gdsep->next; /* set nxt pointer */
570 gdprv = gdsep; /* set prv pointer */
571 gdsep = gdnxt; /* set pointer for next pass */
572
573 } while (gdsep);
574 }
575 }
576
577/*
578
579*/
580 for (; i < (NGDSEL - 1); i++) { /* scan the event priorities ... */
581
582 gdprv = (struct gdsel *)gdstp; /* setup previous pointer */
583 gdsep = *gdstp++; /* setup current pointer */
584
585 if (gdsep) { /* ... process each active event priority ... */
586
587 ++wrote; /* indicate slice was updated */
588
589 do { /* ... for each event of this priority ... */
590
591 /* setup slice and pixel pointers */
592
593 slptr = slice + 212;
594 pxptr = &epxtbl[gdsep->code][0];
595
596 ncolor = gdsep->note; /* get event color */
597
598 /* update the slice */
599
600 if (w = *pxptr++) /* 212 */
601 *slptr = (*slptr & mask2) | (w & ncolor);
602
603 ++slptr;
604
605 if (w = *pxptr++) /* 213 */
606 *slptr = (*slptr & mask2) | (w & ncolor);
607
608 ++slptr;
609
610 if (w = *pxptr++) /* 214 */
611 *slptr = (*slptr & mask2) | (w & ncolor);
612
613 ++slptr;
614
615 if (w = *pxptr++) /* 215 */
616 *slptr = (*slptr & mask2) | (w & ncolor);
617
618 ++slptr;
619
620 if (w = *pxptr++) /* 216 */
621 *slptr = (*slptr & mask2) | (w & ncolor);
622
623 ++slptr;
624
625 if (w = *pxptr++) /* 217 */
626 *slptr = (*slptr & mask2) | (w & ncolor);
627
628 ++slptr;
629
630 if (w = *pxptr++) /* 218 */
631 *slptr = (*slptr & mask2) | (w & ncolor);
632
633 ++slptr;
634
635 if (w = *pxptr++) /* 219 */
636 *slptr = (*slptr & mask2) | (w & ncolor);
637
638 ++slptr;
639
640 if (w = *pxptr++) /* 220 */
641 *slptr = (*slptr & mask2) | (w & ncolor);
642
643 ++slptr;
644
645 if (w = *pxptr++) /* 221 */
646 *slptr = (*slptr & mask2) | (w & ncolor);
647
648 ++slptr;
649
650 if (w = *pxptr++) /* 222 */
651 *slptr = (*slptr & mask2) | (w & ncolor);
652
653 ++slptr;
654
655 if (w = *pxptr) /* 223 */
656 *slptr = (*slptr & mask2) | (w & ncolor);
657
658 gdnxt = gdsep->next; /* set next pointer */
659 gdprv->next = gdnxt; /* delete the element */
660 gdsep->next = gdfsep;
661 gdfsep = gdsep;
662 gdsep = gdnxt; /* set pointer for next pass */
663
664 } while (gdsep);
665 }
666 }
667
668 DB_EXIT(wrote ? "cslice - slice written" : "cslice - no write");
669
670 return(wrote);
671}
672
673/*
674
675*/
676
677/*
678 =============================================================================
679 clrsctl() -- clear slice control list and pointers
680 =============================================================================
681*/
682
683clrsctl()
684{
685 register struct gdsel *gdsp, *gnxt, **gp;
686 register short i;
687
688 gdfsep = gdsp = &gdfsl[0]; /* initialize slice control pool */
689 gnxt = &gdfsl[1];
690
691 for (i = MAXFSL - 1; i--; ) {
692
693 gdsp->code = 0;
694 gdsp->note = 0;
695 gdsp->next = gnxt;
696
697 gdsp++;
698 gnxt++;
699 }
700
701 gdsp->code = 0;
702 gdsp->note = 0;
703 gdsp->next = (struct gdsel *)0L;
704
705 gp = gdstbc; /* clear gdstbc */
706
707 for (i = NGDSEL; i--; )
708 *gp++ = (struct gdsel *)0L;
709
710 gp = gdstbn; /* clear gdstbn */
711
712 for (i = NGDSEL; i--; )
713 *gp++ = (struct gdsel *)0L;
714
715 gp = gdstbp; /* clear gdstbp */
716
717 for (i = NGDSEL; i--; )
718 *gp++ = (struct gdsel *)0L;
719
720 sbase = I_SBASE; /* initialize score video RAM offset */
721 soffset = I_OFFSET; /* initialize scroll register offset */
722 saddr = &v_score[sbase]; /* initialize score area base address */
723
724 consl = &slices[672]; /* initialize constant slice pointer */
725 prvsl = &slices[448]; /* initialize previous slice pointer */
726 cursl = &slices[224]; /* initialize current slice pointer */
727 nxtsl = &slices[0]; /* initialize next slice pointer */
728/*
729
730*/
731 {
732 register unsigned *p1, *p2, *p3, sword;
733 unsigned *p4;
734
735 p1 = consl; /* clear slices */
736 p2 = nxtsl;
737 p3 = cursl;
738 p4 = prvsl;
739
740 for (i = 224; i--; ) {
741
742 sword = *p1++;
743 *p2++ = sword;
744 *p3++ = sword;
745 *p4++ = sword;
746 }
747 }
748}
Note: See TracBrowser for help on using the repository browser.