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

Last change on this file since 202bf8c was 57425b6, checked in by Thomas Lopatic <thomas@…>, 6 years ago

Fixed uslice.c.

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