summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/lib/gray.c157
1 files changed, 83 insertions, 74 deletions
diff --git a/apps/plugins/lib/gray.c b/apps/plugins/lib/gray.c
index cf7063aeeb..ed95a39dea 100644
--- a/apps/plugins/lib/gray.c
+++ b/apps/plugins/lib/gray.c
@@ -77,7 +77,7 @@ static void gray_timer_isr(void)
77 int x1 = MAX(graybuf->x, 0); 77 int x1 = MAX(graybuf->x, 0);
78 int x2 = MIN(graybuf->x + graybuf->width, LCD_WIDTH); 78 int x2 = MIN(graybuf->x + graybuf->width, LCD_WIDTH);
79 int y1 = MAX(graybuf->by << 3, 0); 79 int y1 = MAX(graybuf->by << 3, 0);
80 int y2 = MIN((graybuf->by + graybuf->bheight) << 3, LCD_HEIGHT); 80 int y2 = MIN((graybuf->by << 3) + graybuf->height, LCD_HEIGHT);
81 81
82 if (y1 > 0) /* refresh part above overlay, full width */ 82 if (y1 > 0) /* refresh part above overlay, full width */
83 rb->lcd_update_rect(0, 0, LCD_WIDTH, y1); 83 rb->lcd_update_rect(0, 0, LCD_WIDTH, y1);
@@ -108,7 +108,7 @@ static void graypixel(int x, int y, unsigned long pattern)
108 * It delivers max. 16 pseudo-random bits in each iteration. */ 108 * It delivers max. 16 pseudo-random bits in each iteration. */
109 109
110 /* simple but fast pseudo-random generator */ 110 /* simple but fast pseudo-random generator */
111 asm( 111 asm (
112 "mov #75,r1 \n" 112 "mov #75,r1 \n"
113 "mulu %1,r1 \n" /* multiply by 75 */ 113 "mulu %1,r1 \n" /* multiply by 75 */
114 "sts macl,%1 \n" /* get result */ 114 "sts macl,%1 \n" /* get result */
@@ -126,7 +126,7 @@ static void graypixel(int x, int y, unsigned long pattern)
126 ); 126 );
127 127
128 /* precalculate mask and byte address in first bitplane */ 128 /* precalculate mask and byte address in first bitplane */
129 asm( 129 asm (
130 "mov %3,%0 \n" /* take y as base for address offset */ 130 "mov %3,%0 \n" /* take y as base for address offset */
131 "shlr2 %0 \n" /* shift right by 3 (= divide by 8) */ 131 "shlr2 %0 \n" /* shift right by 3 (= divide by 8) */
132 "shlr %0 \n" 132 "shlr %0 \n"
@@ -164,7 +164,7 @@ static void graypixel(int x, int y, unsigned long pattern)
164 ); 164 );
165 165
166 /* the hard part: set bits in all bitplanes according to pattern */ 166 /* the hard part: set bits in all bitplanes according to pattern */
167 asm( 167 asm volatile (
168 "cmp/hs %1,%5 \n" /* random >= depth ? */ 168 "cmp/hs %1,%5 \n" /* random >= depth ? */
169 "bf .p_ntrim \n" 169 "bf .p_ntrim \n"
170 "sub %1,%5 \n" /* yes: random -= depth */ 170 "sub %1,%5 \n" /* yes: random -= depth */
@@ -240,7 +240,7 @@ static void grayblock(int x, int by, unsigned char* src, int stride)
240 /* precalculate the bit patterns with random shifts (same RNG as graypixel, 240 /* precalculate the bit patterns with random shifts (same RNG as graypixel,
241 * see there for an explanation) for all 8 pixels and put them on an 241 * see there for an explanation) for all 8 pixels and put them on an
242 * extra stack */ 242 * extra stack */
243 asm( 243 asm (
244 "mova .gb_reload,r0 \n" /* set default loopback address */ 244 "mova .gb_reload,r0 \n" /* set default loopback address */
245 "tst %3,%3 \n" /* stride == 0 ? */ 245 "tst %3,%3 \n" /* stride == 0 ? */
246 "bf .gb_needreload \n" /* no: keep that address */ 246 "bf .gb_needreload \n" /* no: keep that address */
@@ -323,7 +323,7 @@ static void grayblock(int x, int by, unsigned char* src, int stride)
323 323
324 /* set the bits for all 8 pixels in all bytes according to the 324 /* set the bits for all 8 pixels in all bytes according to the
325 * precalculated patterns on the pattern stack */ 325 * precalculated patterns on the pattern stack */
326 asm ( 326 asm volatile (
327 "mov.l @%3+,r1 \n" /* pop all 8 patterns */ 327 "mov.l @%3+,r1 \n" /* pop all 8 patterns */
328 "mov.l @%3+,r2 \n" 328 "mov.l @%3+,r2 \n"
329 "mov.l @%3+,r3 \n" 329 "mov.l @%3+,r3 \n"
@@ -368,7 +368,7 @@ static void grayblock(int x, int by, unsigned char* src, int stride)
368/* Invert the bits for 1-8 pixels within the buffer */ 368/* Invert the bits for 1-8 pixels within the buffer */
369static void grayinvertmasked(int x, int by, unsigned char mask) 369static void grayinvertmasked(int x, int by, unsigned char mask)
370{ 370{
371 asm( 371 asm volatile (
372 "mulu %4,%5 \n" /* width * by (offset of row) */ 372 "mulu %4,%5 \n" /* width * by (offset of row) */
373 "mov #0,r1 \n" /* current_plane = 0 */ 373 "mov #0,r1 \n" /* current_plane = 0 */
374 "sts macl,r2 \n" /* get mulu result */ 374 "sts macl,r2 \n" /* get mulu result */
@@ -473,7 +473,7 @@ int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width,
473 graybuf->data = (unsigned char *) (graybuf->bitpattern + depth + 1); 473 graybuf->data = (unsigned char *) (graybuf->bitpattern + depth + 1);
474 graybuf->curfont = FONT_SYSFIXED; 474 graybuf->curfont = FONT_SYSFIXED;
475 475
476 i = depth; 476 i = depth - 1;
477 j = 8; 477 j = 8;
478 while (i != 0) 478 while (i != 0)
479 { 479 {
@@ -660,36 +660,39 @@ void gray_scroll_left(int count, bool black_border)
660 ptr = graybuf->data + MULU16(graybuf->width, by); 660 ptr = graybuf->data + MULU16(graybuf->width, by);
661 for (d = 0; d < graybuf->depth; d++) 661 for (d = 0; d < graybuf->depth; d++)
662 { 662 {
663 if (count & 1) /* odd count: scroll byte-wise */ 663 asm volatile (
664 asm volatile ( 664 "mov %0,r1 \n" /* check if both source... */
665 ".sl_loop1: \n" 665 "or %2,r1 \n" /* ...and offset are even */
666 "mov.b @%0+,r1 \n" 666 "shlr r1 \n" /* -> lsb = 0 */
667 "mov.b r1,@(%2,%0) \n" 667 "bf .sl_start2 \n" /* -> copy word-wise */
668 "cmp/hi %0,%1 \n" 668
669 "bt .sl_loop1 \n" 669 "add #-1,%2 \n" /* copy byte-wise */
670 : /* outputs */ 670 ".sl_loop1: \n"
671 : /* inputs */ 671 "mov.b @%0+,r1 \n"
672 /* %0 */ "r"(ptr + count), 672 "mov.b r1,@(%2,%0) \n"
673 /* %1 */ "r"(ptr + graybuf->width), 673 "cmp/hi %0,%1 \n"
674 /* %2 */ "z"(-count - 1) 674 "bt .sl_loop1 \n"
675 : /* clobbers */ 675
676 "r1" 676 "bra .sl_end \n"
677 ); 677 "nop \n"
678 else /* even count: scroll word-wise */ 678
679 asm volatile ( 679 ".sl_start2: \n" /* copy word-wise */
680 ".sl_loop2: \n" 680 "add #-2,%2 \n"
681 "mov.w @%0+,r1 \n" 681 ".sl_loop2: \n"
682 "mov.w r1,@(%2,%0) \n" 682 "mov.w @%0+,r1 \n"
683 "cmp/hi %0,%1 \n" 683 "mov.w r1,@(%2,%0) \n"
684 "bt .sl_loop2 \n" 684 "cmp/hi %0,%1 \n"
685 : /* outputs */ 685 "bt .sl_loop2 \n"
686 : /* inputs */ 686
687 /* %0 */ "r"(ptr + count), 687 ".sl_end: \n"
688 /* %1 */ "r"(ptr + graybuf->width), 688 : /* outputs */
689 /* %2 */ "z"(-count - 2) 689 : /* inputs */
690 : /* clobbers */ 690 /* %0 */ "r"(ptr + count),
691 "r1" 691 /* %1 */ "r"(ptr + graybuf->width),
692 ); 692 /* %2 */ "z"(-count)
693 : /* clobbers */
694 "r1"
695 );
693 696
694 rb->memset(ptr + graybuf->width - count, filler, count); 697 rb->memset(ptr + graybuf->width - count, filler, count);
695 ptr += graybuf->plane_size; 698 ptr += graybuf->plane_size;
@@ -725,36 +728,39 @@ void gray_scroll_right(int count, bool black_border)
725 ptr = graybuf->data + MULU16(graybuf->width, by); 728 ptr = graybuf->data + MULU16(graybuf->width, by);
726 for (d = 0; d < graybuf->depth; d++) 729 for (d = 0; d < graybuf->depth; d++)
727 { 730 {
728 if (count & 1) /* odd count: scroll byte-wise */ 731 asm volatile (
729 asm volatile ( 732 "mov %0,r1 \n" /* check if both source... */
730 ".sr_loop1: \n" 733 "or %2,r1 \n" /* ...and offset are even */
731 "mov.b @(%2,%0),r1 \n" 734 "shlr r1 \n" /* -> lsb = 0 */
732 "mov.b r1,@-%0 \n" 735 "bf .sr_start2 \n" /* -> copy word-wise */
733 "cmp/hi %1,%0 \n" 736
734 "bt .sr_loop1 \n" 737 "add #-1,%2 \n" /* copy byte-wise */
735 : /* outputs */ 738 ".sr_loop1: \n"
736 : /* inputs */ 739 "mov.b @(%2,%0),r1 \n"
737 /* %0 */ "r"(ptr + graybuf->width), 740 "mov.b r1,@-%0 \n"
738 /* %1 */ "r"(ptr + count), 741 "cmp/hi %1,%0 \n"
739 /* %2 */ "z"(-count - 1) 742 "bt .sr_loop1 \n"
740 : /* clobbers */ 743
741 "r1" 744 "bra .sr_end \n"
742 ); 745 "nop \n"
743 else /* even count: scroll word-wise */ 746
744 asm volatile ( 747 ".sr_start2: \n" /* copy word-wise */
745 ".sr_loop2: \n" 748 "add #-2,%2 \n"
746 "mov.w @(%2,%0),r1 \n" 749 ".sr_loop2: \n"
747 "mov.w r1,@-%0 \n" 750 "mov.w @(%2,%0),r1 \n"
748 "cmp/hi %1,%0 \n" 751 "mov.w r1,@-%0 \n"
749 "bt .sr_loop2 \n" 752 "cmp/hi %1,%0 \n"
750 : /* outputs */ 753 "bt .sr_loop2 \n"
751 : /* inputs */ 754
752 /* %0 */ "r"(ptr + graybuf->width), 755 ".sr_end: \n"
753 /* %1 */ "r"(ptr + count), 756 : /* outputs */
754 /* %2 */ "z"(-count - 2) 757 : /* inputs */
755 : /* clobbers */ 758 /* %0 */ "r"(ptr + graybuf->width),
756 "r1" 759 /* %1 */ "r"(ptr + count),
757 ); 760 /* %2 */ "z"(-count)
761 : /* clobbers */
762 "r1"
763 );
758 764
759 rb->memset(ptr, filler, count); 765 rb->memset(ptr, filler, count);
760 ptr += graybuf->plane_size; 766 ptr += graybuf->plane_size;
@@ -864,7 +870,7 @@ void gray_scroll_up(int count, bool black_border)
864 filler = 0; 870 filler = 0;
865 871
866 /* scroll column by column to minimize flicker */ 872 /* scroll column by column to minimize flicker */
867 asm( 873 asm volatile (
868 "mov #0,r6 \n" /* x = 0 */ 874 "mov #0,r6 \n" /* x = 0 */
869 "mova .su_shifttbl,r0 \n" /* calculate jump destination for */ 875 "mova .su_shifttbl,r0 \n" /* calculate jump destination for */
870 "mov.b @(r0,%6),%6 \n" /* shift amount from table */ 876 "mov.b @(r0,%6),%6 \n" /* shift amount from table */
@@ -967,7 +973,7 @@ void gray_scroll_down(int count, bool black_border)
967 filler = 0; 973 filler = 0;
968 974
969 /* scroll column by column to minimize flicker */ 975 /* scroll column by column to minimize flicker */
970 asm( 976 asm volatile (
971 "mov #0,r6 \n" /* x = 0 */ 977 "mov #0,r6 \n" /* x = 0 */
972 "mova .sd_shifttbl,r0 \n" /* calculate jump destination for */ 978 "mova .sd_shifttbl,r0 \n" /* calculate jump destination for */
973 "mov.b @(r0,%6),%6 \n" /* shift amount from table */ 979 "mov.b @(r0,%6),%6 \n" /* shift amount from table */
@@ -1431,7 +1437,7 @@ void gray_invertrect(int x1, int y1, int x2, int y2)
1431void gray_drawgraymap(unsigned char *src, int x, int y, int nx, int ny, 1437void gray_drawgraymap(unsigned char *src, int x, int y, int nx, int ny,
1432 int stride) 1438 int stride)
1433{ 1439{
1434 int xi, yi; 1440 int xi, yi, byte;
1435 unsigned char *row; 1441 unsigned char *row;
1436 1442
1437 if (graybuf == NULL 1443 if (graybuf == NULL
@@ -1464,7 +1470,9 @@ void gray_drawgraymap(unsigned char *src, int x, int y, int nx, int ny,
1464 { 1470 {
1465 for (xi = x; xi < x + nx; xi++) 1471 for (xi = x; xi < x + nx; xi++)
1466 { 1472 {
1467 graypixel(xi, yi, graybuf->bitpattern[MULU16(*row++, 1473 byte = *row++;
1474 /* separated to force GCC to use 16bit multiplication below */
1475 graypixel(xi, yi, graybuf->bitpattern[MULU16(byte,
1468 graybuf->depth + 1) >> 8]); 1476 graybuf->depth + 1) >> 8]);
1469 } 1477 }
1470 yi++; 1478 yi++;
@@ -1609,8 +1617,9 @@ void gray_putsxy(int x, int y, unsigned char *str, bool draw_bg,
1609 1617
1610 /* get proportional width and glyph bits */ 1618 /* get proportional width and glyph bits */
1611 width = pf->width ? pf->width[ch] : pf->maxwidth; 1619 width = pf->width ? pf->width[ch] : pf->maxwidth;
1612 bits = pf->bits + (pf->offset ? pf->offset[ch] : (pf->height * ch)); 1620 bits = pf->bits + (pf->offset ? pf->offset[ch]
1613 1621 : MULU16(pf->height, ch));
1622
1614 gray_drawbitmap((unsigned char*) bits, x, y, width, pf->height, 1623 gray_drawbitmap((unsigned char*) bits, x, y, width, pf->height,
1615 width, draw_bg, fg_brightness, bg_brightness); 1624 width, draw_bg, fg_brightness, bg_brightness);
1616 x += width; 1625 x += width;