diff options
Diffstat (limited to 'apps/plugins/lib/gray_core.c')
-rw-r--r-- | apps/plugins/lib/gray_core.c | 132 |
1 files changed, 75 insertions, 57 deletions
diff --git a/apps/plugins/lib/gray_core.c b/apps/plugins/lib/gray_core.c index a4ef45d8c1..ecff53f1c5 100644 --- a/apps/plugins/lib/gray_core.c +++ b/apps/plugins/lib/gray_core.c | |||
@@ -81,10 +81,8 @@ static void _timer_isr(void) | |||
81 | memory. Unbuffered operation provides only a subset of | 81 | memory. Unbuffered operation provides only a subset of |
82 | drawing functions. (only gray_bitmap drawing and scrolling) | 82 | drawing functions. (only gray_bitmap drawing and scrolling) |
83 | width = width in pixels (1..LCD_WIDTH) | 83 | width = width in pixels (1..LCD_WIDTH) |
84 | bheight = height in LCD pixel-block units (8 pixels for b&w LCD, | 84 | bheight = height in LCD pixel-block units (8 pixels) (1..LCD_HEIGHT/8) |
85 | 4 pixels for 4-grey LCD) (1..LCD_HEIGHT/block_size) | 85 | depth = number of bitplanes to use (1..32). |
86 | depth = number of bitplanes to use (1..32 for b&w LCD, 1..16 for | ||
87 | 4-grey LCD). | ||
88 | 86 | ||
89 | result: | 87 | result: |
90 | = depth if there was enough memory | 88 | = depth if there was enough memory |
@@ -99,8 +97,7 @@ static void _timer_isr(void) | |||
99 | deliver an enhancement over the native display. | 97 | deliver an enhancement over the native display. |
100 | 98 | ||
101 | The number of displayable shades is calculated as follows: | 99 | The number of displayable shades is calculated as follows: |
102 | b&w LCD: shades = depth + 1 | 100 | shades = depth + 1 |
103 | 4-grey LCD: shades = 3 * depth + 1 | ||
104 | 101 | ||
105 | If you need info about the memory taken by the greyscale buffer, supply a | 102 | If you need info about the memory taken by the greyscale buffer, supply a |
106 | long* as the last parameter. This long will then contain the number of bytes | 103 | long* as the last parameter. This long will then contain the number of bytes |
@@ -109,7 +106,7 @@ static void _timer_isr(void) | |||
109 | shades * sizeof(long) (bitpatterns) | 106 | shades * sizeof(long) (bitpatterns) |
110 | + (width * bheight) * depth (bitplane data) | 107 | + (width * bheight) * depth (bitplane data) |
111 | + buffered ? (chunky front- & backbuffer) | 108 | + buffered ? (chunky front- & backbuffer) |
112 | (width * bheight * 8(4) * 2) : 0 | 109 | (width * bheight * 8 * 2) : 0 |
113 | + 0..3 (longword alignment) */ | 110 | + 0..3 (longword alignment) */ |
114 | int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, | 111 | int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, |
115 | bool buffered, int width, int bheight, int depth, long *buf_taken) | 112 | bool buffered, int width, int bheight, int depth, long *buf_taken) |
@@ -292,42 +289,41 @@ void gray_update_rect(int x, int y, int width, int height) | |||
292 | #if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) | 289 | #if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) |
293 | unsigned long pat_stack[8]; | 290 | unsigned long pat_stack[8]; |
294 | unsigned long *pat_ptr; | 291 | unsigned long *pat_ptr; |
295 | unsigned change, ofs; | 292 | unsigned char *cbuf, *bbuf; |
293 | unsigned change; | ||
294 | |||
295 | cbuf = _gray_info.cur_buffer + srcofs_row; | ||
296 | bbuf = _gray_info.back_buffer + srcofs_row; | ||
296 | 297 | ||
297 | ofs = srcofs_row; | ||
298 | asm volatile ( | 298 | asm volatile ( |
299 | "mov.l @(%[ofs],%[cbuf]),r1\n" | 299 | "mov.l @%[cbuf]+,r1 \n" |
300 | "mov.l @(%[ofs],%[bbuf]),r2\n" | 300 | "mov.l @%[bbuf]+,r2 \n" |
301 | "xor r1,r2 \n" | 301 | "xor r1,r2 \n" |
302 | "add #4,%[ofs] \n" | 302 | "mov.l @%[cbuf],r1 \n" |
303 | "mov.l @(%[ofs],%[cbuf]),r1\n" | 303 | "mov.l @%[bbuf],%[chg] \n" |
304 | "mov.l @(%[ofs],%[bbuf]),%[chg]\n" | ||
305 | "xor r1,%[chg] \n" | 304 | "xor r1,%[chg] \n" |
306 | "or r2,%[chg] \n" | 305 | "or r2,%[chg] \n" |
307 | : /* outputs */ | 306 | : /* outputs */ |
308 | [ofs] "+z"(ofs), | 307 | [cbuf]"+r"(cbuf), |
308 | [bbuf]"+r"(bbuf), | ||
309 | [chg] "=r"(change) | 309 | [chg] "=r"(change) |
310 | : /* inputs */ | 310 | : /* inputs */ |
311 | [cbuf]"r"(_gray_info.cur_buffer), | ||
312 | [bbuf]"r"(_gray_info.back_buffer) | ||
313 | : /* clobbers */ | 311 | : /* clobbers */ |
314 | "r1", "r2" | 312 | "r1", "r2" |
315 | ); | 313 | ); |
316 | 314 | ||
317 | if (change != 0) | 315 | if (change != 0) |
318 | { | 316 | { |
319 | unsigned char *cbuf, *bbuf, *addr, *end; | 317 | unsigned char *addr, *end; |
320 | unsigned mask; | 318 | unsigned mask; |
321 | 319 | ||
322 | pat_ptr = &pat_stack[8]; | 320 | pat_ptr = &pat_stack[8]; |
323 | cbuf = _gray_info.cur_buffer; | 321 | cbuf = _gray_info.cur_buffer + srcofs_row; |
324 | bbuf = _gray_info.back_buffer; | 322 | bbuf = _gray_info.back_buffer + srcofs_row; |
325 | 323 | ||
326 | /* precalculate the bit patterns with random shifts | 324 | /* precalculate the bit patterns with random shifts |
327 | * for all 8 pixels and put them on an extra "stack" */ | 325 | * for all 8 pixels and put them on an extra "stack" */ |
328 | asm volatile ( | 326 | asm volatile ( |
329 | "add %[ofs],%[cbuf] \n" | ||
330 | "add %[ofs],%[bbuf] \n" | ||
331 | "mov #8,r3 \n" /* loop count in r3: 8 pixels */ | 327 | "mov #8,r3 \n" /* loop count in r3: 8 pixels */ |
332 | 328 | ||
333 | ".ur_pre_loop: \n" | 329 | ".ur_pre_loop: \n" |
@@ -384,7 +380,6 @@ void gray_update_rect(int x, int y, int width, int height) | |||
384 | [patp]"+r"(pat_ptr), | 380 | [patp]"+r"(pat_ptr), |
385 | [mask]"=&r"(mask) | 381 | [mask]"=&r"(mask) |
386 | : /* inputs */ | 382 | : /* inputs */ |
387 | [ofs] "[mask]"(srcofs_row), | ||
388 | [dpth]"r"(_gray_info.depth), | 383 | [dpth]"r"(_gray_info.depth), |
389 | [bpat]"r"(_gray_info.bitpattern), | 384 | [bpat]"r"(_gray_info.bitpattern), |
390 | [rmsk]"r"(_gray_info.randmask) | 385 | [rmsk]"r"(_gray_info.randmask) |
@@ -473,36 +468,44 @@ void gray_update_rect(int x, int y, int width, int height) | |||
473 | ); | 468 | ); |
474 | } | 469 | } |
475 | #elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) | 470 | #elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) |
476 | unsigned long pat_stack[4]; | 471 | unsigned long pat_stack[8]; |
477 | unsigned long *pat_ptr; | 472 | unsigned long *pat_ptr; |
473 | unsigned char *cbuf, *bbuf; | ||
478 | unsigned change; | 474 | unsigned change; |
479 | 475 | ||
476 | cbuf = _gray_info.cur_buffer + srcofs_row; | ||
477 | bbuf = _gray_info.back_buffer + srcofs_row; | ||
478 | |||
480 | asm volatile ( | 479 | asm volatile ( |
481 | "move.l (%[ofs]:l:1,%[cbuf]),%[chg] \n" | 480 | "move.l (%[cbuf])+,%%d0 \n" |
482 | "sub.l (%[ofs]:l:1,%[bbuf]),%[chg] \n" | 481 | "move.l (%[bbuf])+,%%d1 \n" |
482 | "eor.l %%d0,%%d1 \n" | ||
483 | "move.l (%[cbuf]),%%d0 \n" | ||
484 | "move.l (%[bbuf]),%[chg]\n" | ||
485 | "eor.l %%d0,%[chg] \n" | ||
486 | "or.l %%d1,%[chg] \n" | ||
483 | : /* outputs */ | 487 | : /* outputs */ |
488 | [cbuf]"+a"(cbuf), | ||
489 | [bbuf]"+a"(bbuf), | ||
484 | [chg] "=&d"(change) | 490 | [chg] "=&d"(change) |
485 | : /* inputs */ | 491 | : /* inputs */ |
486 | [cbuf]"a"(_gray_info.cur_buffer), | 492 | : /* clobbers */ |
487 | [bbuf]"a"(_gray_info.back_buffer), | 493 | "d0", "d1" |
488 | [ofs] "d"(srcofs_row) | ||
489 | ); | 494 | ); |
490 | 495 | ||
491 | if (change != 0) | 496 | if (change != 0) |
492 | { | 497 | { |
493 | unsigned char *cbuf, *bbuf, *addr, *end; | 498 | unsigned char *addr, *end; |
494 | unsigned mask; | 499 | unsigned mask; |
495 | 500 | ||
496 | pat_ptr = &pat_stack[4]; | 501 | pat_ptr = &pat_stack[8]; |
497 | cbuf = _gray_info.cur_buffer; | 502 | cbuf = _gray_info.cur_buffer + srcofs_row; |
498 | bbuf = _gray_info.back_buffer; | 503 | bbuf = _gray_info.back_buffer + srcofs_row; |
499 | 504 | ||
500 | /* precalculate the bit patterns with random shifts | 505 | /* precalculate the bit patterns with random shifts |
501 | * for all 4 pixels and put them on an extra "stack" */ | 506 | * for all 8 pixels and put them on an extra "stack" */ |
502 | asm volatile ( | 507 | asm volatile ( |
503 | "add.l %[ofs],%[cbuf] \n" | 508 | "moveq.l #8,%%d3 \n" /* loop count in d3: 8 pixels */ |
504 | "add.l %[ofs],%[bbuf] \n" | ||
505 | "moveq.l #4,%%d3 \n" /* loop count in d3: 4 pixels */ | ||
506 | "clr.l %[mask] \n" | 509 | "clr.l %[mask] \n" |
507 | 510 | ||
508 | ".ur_pre_loop: \n" | 511 | ".ur_pre_loop: \n" |
@@ -536,10 +539,10 @@ void gray_update_rect(int x, int y, int width, int height) | |||
536 | "lsr.l %%d1,%%d2 \n" | 539 | "lsr.l %%d1,%%d2 \n" |
537 | "or.l %%d0,%%d2 \n" /* rotated_pattern = d2 | d0 */ | 540 | "or.l %%d0,%%d2 \n" /* rotated_pattern = d2 | d0 */ |
538 | 541 | ||
539 | "or.l #0x0300,%[mask] \n" /* set mask bit */ | 542 | "or.l #0x0100,%[mask] \n" /* set mask bit */ |
540 | 543 | ||
541 | ".ur_skip: \n" | 544 | ".ur_skip: \n" |
542 | "lsr.l #2,%[mask] \n" /* shift mask */ | 545 | "lsr.l #1,%[mask] \n" /* shift mask */ |
543 | "move.l %%d2,-(%[patp]) \n" /* push on pattern stack */ | 546 | "move.l %%d2,-(%[patp]) \n" /* push on pattern stack */ |
544 | 547 | ||
545 | "subq.l #1,%%d3 \n" /* decrease loop count */ | 548 | "subq.l #1,%%d3 \n" /* decrease loop count */ |
@@ -551,7 +554,6 @@ void gray_update_rect(int x, int y, int width, int height) | |||
551 | [rnd] "+d"(_gray_random_buffer), | 554 | [rnd] "+d"(_gray_random_buffer), |
552 | [mask]"=&d"(mask) | 555 | [mask]"=&d"(mask) |
553 | : /* inputs */ | 556 | : /* inputs */ |
554 | [ofs] "[mask]"(srcofs_row), | ||
555 | [bpat]"a"(_gray_info.bitpattern), | 557 | [bpat]"a"(_gray_info.bitpattern), |
556 | [dpth]"d"(_gray_info.depth), | 558 | [dpth]"d"(_gray_info.depth), |
557 | [rmsk]"d"(_gray_info.randmask) | 559 | [rmsk]"d"(_gray_info.randmask) |
@@ -562,11 +564,11 @@ void gray_update_rect(int x, int y, int width, int height) | |||
562 | addr = dst_row; | 564 | addr = dst_row; |
563 | end = addr + MULU16(_gray_info.depth, _gray_info.plane_size); | 565 | end = addr + MULU16(_gray_info.depth, _gray_info.plane_size); |
564 | 566 | ||
565 | /* set the bits for all 4 pixels in all bytes according to the | 567 | /* set the bits for all 8 pixels in all bytes according to the |
566 | * precalculated patterns on the pattern stack */ | 568 | * precalculated patterns on the pattern stack */ |
567 | asm volatile ( | 569 | asm volatile ( |
568 | "movem.l (%[patp]),%%d2-%%d5 \n" /* pop all 4 patterns */ | 570 | "movem.l (%[patp]),%%d2-%%d6/%%a0-%%a2 \n" |
569 | 571 | /* pop all 8 patterns */ | |
570 | "not.l %[mask] \n" /* set mask -> keep mask */ | 572 | "not.l %[mask] \n" /* set mask -> keep mask */ |
571 | "and.l #0xFF,%[mask] \n" | 573 | "and.l #0xFF,%[mask] \n" |
572 | "beq.b .ur_sloop \n" /* yes: jump to short loop */ | 574 | "beq.b .ur_sloop \n" /* yes: jump to short loop */ |
@@ -575,18 +577,26 @@ void gray_update_rect(int x, int y, int width, int height) | |||
575 | "clr.l %%d0 \n" | 577 | "clr.l %%d0 \n" |
576 | "lsr.l #1,%%d2 \n" /* shift out mask bit */ | 578 | "lsr.l #1,%%d2 \n" /* shift out mask bit */ |
577 | "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */ | 579 | "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */ |
578 | "lsl.l #1,%%d0 \n" /* shift by another 1 for a total of 2 */ | ||
579 | "lsr.l #1,%%d3 \n" | 580 | "lsr.l #1,%%d3 \n" |
580 | "addx.l %%d0,%%d0 \n" | 581 | "addx.l %%d0,%%d0 \n" |
581 | "lsl.l #1,%%d0 \n" | ||
582 | "lsr.l #1,%%d4 \n" | 582 | "lsr.l #1,%%d4 \n" |
583 | "addx.l %%d0,%%d0 \n" | 583 | "addx.l %%d0,%%d0 \n" |
584 | "lsl.l #1,%%d0 \n" | ||
585 | "lsr.l #1,%%d5 \n" | 584 | "lsr.l #1,%%d5 \n" |
586 | "addx.l %%d0,%%d0 \n" | 585 | "addx.l %%d0,%%d0 \n" |
587 | "move.l %%d0,%%d1 \n" /* duplicate bits 0, 2, 4, 6, ... */ | 586 | "lsr.l #1,%%d6 \n" |
588 | "lsl.l #1,%%d1 \n" /* to 1, 3, 5, 7, ... */ | 587 | "addx.l %%d0,%%d0 \n" |
589 | "or.l %%d1,%%d0 \n" | 588 | "move.l %%a0,%%d1 \n" |
589 | "lsr.l #1,%%d1 \n" | ||
590 | "addx.l %%d0,%%d0 \n" | ||
591 | "move.l %%d1,%%a0 \n" | ||
592 | "move.l %%a1,%%d1 \n" | ||
593 | "lsr.l #1,%%d1 \n" | ||
594 | "addx.l %%d0,%%d0 \n" | ||
595 | "move.l %%d1,%%a1 \n" | ||
596 | "move.l %%a2,%%d1 \n" | ||
597 | "lsr.l #1,%%d1 \n" | ||
598 | "addx.l %%d0,%%d0 \n" | ||
599 | "move.l %%d1,%%a2 \n" | ||
590 | 600 | ||
591 | "move.b (%[addr]),%%d1 \n" /* read old value */ | 601 | "move.b (%[addr]),%%d1 \n" /* read old value */ |
592 | "and.l %[mask],%%d1 \n" /* mask out unneeded bits */ | 602 | "and.l %[mask],%%d1 \n" /* mask out unneeded bits */ |
@@ -603,18 +613,26 @@ void gray_update_rect(int x, int y, int width, int height) | |||
603 | "clr.l %%d0 \n" | 613 | "clr.l %%d0 \n" |
604 | "lsr.l #1,%%d2 \n" /* shift out mask bit */ | 614 | "lsr.l #1,%%d2 \n" /* shift out mask bit */ |
605 | "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */ | 615 | "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */ |
606 | "lsl.l #1,%%d0 \n" /* shift by another 1 for a total of 2 */ | ||
607 | "lsr.l #1,%%d3 \n" | 616 | "lsr.l #1,%%d3 \n" |
608 | "addx.l %%d0,%%d0 \n" | 617 | "addx.l %%d0,%%d0 \n" |
609 | "lsl.l #1,%%d0 \n" | ||
610 | "lsr.l #1,%%d4 \n" | 618 | "lsr.l #1,%%d4 \n" |
611 | "addx.l %%d0,%%d0 \n" | 619 | "addx.l %%d0,%%d0 \n" |
612 | "lsl.l #1,%%d0 \n" | ||
613 | "lsr.l #1,%%d5 \n" | 620 | "lsr.l #1,%%d5 \n" |
614 | "addx.l %%d0,%%d0 \n" | 621 | "addx.l %%d0,%%d0 \n" |
615 | "move.l %%d0,%%d1 \n" /* duplicate bits 0, 2, 4, 6, ... */ | 622 | "lsr.l #1,%%d6 \n" |
616 | "lsl.l #1,%%d1 \n" /* to 1, 3, 5, 7, ... */ | 623 | "addx.l %%d0,%%d0 \n" |
617 | "or.l %%d1,%%d0 \n" | 624 | "move.l %%a0,%%d1 \n" |
625 | "lsr.l #1,%%d1 \n" | ||
626 | "addx.l %%d0,%%d0 \n" | ||
627 | "move.l %%d1,%%a0 \n" | ||
628 | "move.l %%a1,%%d1 \n" | ||
629 | "lsr.l #1,%%d1 \n" | ||
630 | "addx.l %%d0,%%d0 \n" | ||
631 | "move.l %%d1,%%a1 \n" | ||
632 | "move.l %%a2,%%d1 \n" | ||
633 | "lsr.l #1,%%d1 \n" | ||
634 | "addx.l %%d0,%%d0 \n" | ||
635 | "move.l %%d1,%%a2 \n" | ||
618 | 636 | ||
619 | "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */ | 637 | "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */ |
620 | "add.l %[psiz],%[addr] \n" /* advance to next bitplane */ | 638 | "add.l %[psiz],%[addr] \n" /* advance to next bitplane */ |
@@ -626,11 +644,11 @@ void gray_update_rect(int x, int y, int width, int height) | |||
626 | [addr]"+a"(addr), | 644 | [addr]"+a"(addr), |
627 | [mask]"+d"(mask) | 645 | [mask]"+d"(mask) |
628 | : /* inputs */ | 646 | : /* inputs */ |
629 | [psiz]"r"(_gray_info.plane_size), | 647 | [psiz]"a"(_gray_info.plane_size), |
630 | [end] "a"(end), | 648 | [end] "a"(end), |
631 | [patp]"a"(pat_ptr) | 649 | [patp]"a"(pat_ptr) |
632 | : /* clobbers */ | 650 | : /* clobbers */ |
633 | "d0", "d1", "d2", "d3", "d4", "d5" | 651 | "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1", "a2" |
634 | ); | 652 | ); |
635 | } | 653 | } |
636 | #endif | 654 | #endif |