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

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

Point of no return.

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