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

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

Removed form-feed comments.

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