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

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

Zero redundant declarations.

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