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

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

Added include files for global functions and variables.

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