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

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

More volatile hardware accesses.

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