diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES index 4b625cc5f8..4d4247e3bb 100644 --- a/apps/plugins/lib/SOURCES +++ b/apps/plugins/lib/SOURCES @@ -1,6 +1,6 @@ configfile.c highscore.c -#if (CONFIG_LCD == LCD_SSD1815) && !defined(SIMULATOR) +#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) && !defined(SIMULATOR) gray_core.c gray_draw.c gray_parm.c diff --git a/apps/plugins/lib/gray.h b/apps/plugins/lib/gray.h index 8abf7bc16d..09ae73b8a6 100644 --- a/apps/plugins/lib/gray.h +++ b/apps/plugins/lib/gray.h @@ -113,8 +113,6 @@ void gray_ub_scroll_down(int count); #define _PBLOCK_EXP 2 #endif #define _PBLOCK (1 << _PBLOCK_EXP) -#define _MAX_DEPTH (32 / LCD_DEPTH) -#define _LEVEL_FAC ((1 << LCD_DEPTH) - 1) /* flag definitions */ #define _GRAY_RUNNING 0x0001 /* greyscale overlay is running */ diff --git a/apps/plugins/lib/gray_core.c b/apps/plugins/lib/gray_core.c index 361b392458..a4ef45d8c1 100644 --- a/apps/plugins/lib/gray_core.c +++ b/apps/plugins/lib/gray_core.c @@ -146,12 +146,12 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, plane_size = MULU16(width, bheight); possible_depth = (gbuf_size - buftaken - sizeof(long)) - / (plane_size + _LEVEL_FAC * sizeof(long)); + / (plane_size + sizeof(long)); if (possible_depth < 1) return 0; - depth = MIN(depth, _MAX_DEPTH); + depth = MIN(depth, 32); depth = MIN(depth, possible_depth); _gray_info.x = 0; @@ -166,9 +166,8 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, _gray_info.plane_data = gbuf; gbuf += depth * plane_size; _gray_info.bitpattern = (unsigned long *)gbuf; - buftaken += depth * plane_size - + (_LEVEL_FAC * depth + 1) * sizeof(long); - + buftaken += depth * plane_size + (depth + 1) * sizeof(long); + i = depth - 1; j = 8; while (i != 0) @@ -179,7 +178,6 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, _gray_info.randmask = 0xFFu >> j; /* Precalculate the bit patterns for all possible pixel values */ -#if LCD_DEPTH == 1 for (i = 0; i <= depth; i++) { unsigned long pattern = 0; @@ -199,33 +197,9 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, _gray_info.bitpattern[i] = pattern; } -#elif LCD_DEPTH == 2 - for (i = 0; i < depth; i++) - { - unsigned long pattern = 0; - int value = 0; - - for (j = 0; j < depth; j++) - { - pattern <<= 2; - value += i; - - if (value >= depth) - value -= depth; - else - pattern |= 3; - } - - _gray_info.bitpattern[i] = pattern | (~pattern & 0xaaaaaaaa); - _gray_info.bitpattern[i+depth] = (pattern & 0xaaaaaaaa) - | (~pattern & 0x55555555); - _gray_info.bitpattern[i+2*depth] = pattern & 0x55555555; - } - _gray_info.bitpattern[3*depth] = 0; -#endif /* LCD_DEPTH */ _gray_info.fg_brightness = 0; - _gray_info.bg_brightness = _LEVEL_FAC * depth; + _gray_info.bg_brightness = depth; _gray_info.drawmode = DRMODE_SOLID; _gray_info.curfont = FONT_SYSFIXED; @@ -254,6 +228,7 @@ void gray_release(void) lcd_set_invert_display(), lcd_set_flip(), lcd_roll() */ void gray_show(bool enable) { +#if (CONFIG_CPU == SH7034) && (CONFIG_LCD == LCD_SSD1815) if (enable) { _gray_info.flags |= _GRAY_RUNNING; @@ -265,6 +240,22 @@ void gray_show(bool enable) _gray_info.flags &= ~_GRAY_RUNNING; _gray_rb->lcd_update(); /* restore whatever there was before */ } +#elif defined(CPU_COLDFIRE) && (CONFIG_LCD == LCD_S1D15E06) + if (enable && !(_gray_info.flags & _GRAY_RUNNING)) + { + _gray_info.flags |= _GRAY_RUNNING; + _gray_rb->cpu_boost(true); /* run at 120 MHz to avoid freq changes */ + _gray_rb->timer_register(1, NULL, *_gray_rb->cpu_frequency / 70, 1, + _timer_isr); + } + else if (!enable && (_gray_info.flags & _GRAY_RUNNING)) + { + _gray_rb->timer_unregister(); + _gray_rb->cpu_boost(false); + _gray_info.flags &= ~_GRAY_RUNNING; + _gray_rb->lcd_update(); /* restore whatever there was before */ + } +#endif } /* Update a rectangular area of the greyscale overlay */ @@ -299,72 +290,76 @@ void gray_update_rect(int x, int y, int width, int height) do { #if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) - unsigned mask; - unsigned long change; unsigned long pat_stack[8]; unsigned long *pat_ptr; - unsigned char *end_addr; + unsigned change, ofs; - asm ( - "mov.l @(%3,%1),r1 \n" - "mov.l @(%3,%2),r2 \n" + ofs = srcofs_row; + asm volatile ( + "mov.l @(%[ofs],%[cbuf]),r1\n" + "mov.l @(%[ofs],%[bbuf]),r2\n" "xor r1,r2 \n" - "add #4,%3 \n" - "mov.l @(%3,%1),r1 \n" - "mov.l @(%3,%2),%0 \n" - "xor r1,%0 \n" - "or r2,%0 \n" + "add #4,%[ofs] \n" + "mov.l @(%[ofs],%[cbuf]),r1\n" + "mov.l @(%[ofs],%[bbuf]),%[chg]\n" + "xor r1,%[chg] \n" + "or r2,%[chg] \n" : /* outputs */ - /* %0 */ "=r"(change) + [ofs] "+z"(ofs), + [chg] "=r"(change) : /* inputs */ - /* %1 */ "r"(_gray_info.cur_buffer), - /* %2 */ "r"(_gray_info.back_buffer), - /* %3 */ "z"(srcofs_row) + [cbuf]"r"(_gray_info.cur_buffer), + [bbuf]"r"(_gray_info.back_buffer) : /* clobbers */ "r1", "r2" ); if (change != 0) { + unsigned char *cbuf, *bbuf, *addr, *end; + unsigned mask; + pat_ptr = &pat_stack[8]; + cbuf = _gray_info.cur_buffer; + bbuf = _gray_info.back_buffer; /* precalculate the bit patterns with random shifts * for all 8 pixels and put them on an extra "stack" */ asm volatile ( - "add %5,%3 \n" - "add %5,%4 \n" + "add %[ofs],%[cbuf] \n" + "add %[ofs],%[bbuf] \n" "mov #8,r3 \n" /* loop count in r3: 8 pixels */ ".ur_pre_loop: \n" - "mov.b @%3+,r0 \n" /* read current buffer */ - "mov.b @%4,r1 \n" /* read back buffer */ + "mov.b @%[cbuf]+,r0\n" /* read current buffer */ + "mov.b @%[bbuf],r1 \n" /* read back buffer */ "mov #0,r2 \n" /* preset for skipped pixel */ - "mov.b r0,@%4 \n" /* update back buffer */ - "add #1,%4 \n" + "mov.b r0,@%[bbuf] \n" /* update back buffer */ + "add #1,%[bbuf] \n" "cmp/eq r0,r1 \n" /* no change? */ "bt .ur_skip \n" /* -> skip */ "shll2 r0 \n" /* pixel value -> pattern offset */ - "mov.l @(r0,%7),r4 \n" /* r4 = bitpattern[byte]; */ + "mov.l @(r0,%[bpat]),r4\n" /* r4 = bitpattern[byte]; */ "mov #75,r0 \n" - "mulu r0,%0 \n" /* multiply by 75 */ - "sts macl,%0 \n" - "add #74,%0 \n" /* add another 74 */ + "mulu r0,%[rnd] \n" /* multiply by 75 */ + "sts macl,%[rnd] \n" + "add #74,%[rnd] \n" /* add another 74 */ /* Since the lower bits are not very random: */ - "swap.b %0,r1 \n" /* get bits 8..15 (need max. 5) */ - "and %8,r1 \n" /* mask out unneeded bits */ + "swap.b %[rnd],r1 \n" /* get bits 8..15 (need max. 5) */ + "and %[rmsk],r1 \n" /* mask out unneeded bits */ - "cmp/hs %6,r1 \n" /* random >= depth ? */ + "cmp/hs %[dpth],r1 \n" /* random >= depth ? */ "bf .ur_ntrim \n" - "sub %6,r1 \n" /* yes: random -= depth; */ + "sub %[dpth],r1 \n" /* yes: random -= depth; */ ".ur_ntrim: \n" "mov.l .ashlsi3,r0 \n" /** rotate pattern **/ "jsr @r0 \n" /* r4 -> r0, shift left by r5 */ "mov r1,r5 \n" - "mov %6,r5 \n" + "mov %[dpth],r5 \n" "sub r1,r5 \n" /* r5 = depth - r1 */ "mov.l .lshrsi3,r1 \n" "jsr @r1 \n" /* r4 -> r0, shift right by r5 */ @@ -374,44 +369,45 @@ void gray_update_rect(int x, int y, int width, int height) "clrt \n" /* mask bit = 0 (replace) */ ".ur_skip: \n" /* T == 1 if skipped */ - "rotcr %2 \n" /* get mask bit */ - "mov.l r2,@-%1 \n" /* push on pattern stack */ + "rotcr %[mask] \n" /* get mask bit */ + "mov.l r2,@-%[patp]\n" /* push on pattern stack */ "add #-1,r3 \n" /* decrease loop count */ "cmp/pl r3 \n" /* loop count > 0? */ "bt .ur_pre_loop\n" /* yes: loop */ - "shlr8 %2 \n" - "shlr16 %2 \n" + "shlr8 %[mask] \n" + "shlr16 %[mask] \n" : /* outputs */ - /* %0, in & out */ "+r"(_gray_random_buffer), - /* %1, in & out */ "+r"(pat_ptr), - /* %2 */ "=&r"(mask) + [cbuf]"+r"(cbuf), + [bbuf]"+r"(bbuf), + [rnd] "+r"(_gray_random_buffer), + [patp]"+r"(pat_ptr), + [mask]"=&r"(mask) : /* inputs */ - /* %3 */ "r"(_gray_info.cur_buffer), - /* %4 */ "r"(_gray_info.back_buffer), - /* %5 */ "2"(srcofs_row), - /* %6 */ "r"(_gray_info.depth), - /* %7 */ "r"(_gray_info.bitpattern), - /* %8 */ "r"(_gray_info.randmask) + [ofs] "[mask]"(srcofs_row), + [dpth]"r"(_gray_info.depth), + [bpat]"r"(_gray_info.bitpattern), + [rmsk]"r"(_gray_info.randmask) : /* clobbers */ "r0", "r1", "r2", "r3", "r4", "r5", "macl", "pr" ); - end_addr = dst_row + MULU16(_gray_info.depth, _gray_info.plane_size); + addr = dst_row; + end = addr + MULU16(_gray_info.depth, _gray_info.plane_size); /* set the bits for all 8 pixels in all bytes according to the * precalculated patterns on the pattern stack */ - asm ( - "mov.l @%3+,r1 \n" /* pop all 8 patterns */ - "mov.l @%3+,r2 \n" - "mov.l @%3+,r3 \n" - "mov.l @%3+,r6 \n" - "mov.l @%3+,r7 \n" - "mov.l @%3+,r8 \n" - "mov.l @%3+,r9 \n" - "mov.l @%3+,r10 \n" + asm volatile ( + "mov.l @%[patp]+,r1\n" /* pop all 8 patterns */ + "mov.l @%[patp]+,r2\n" + "mov.l @%[patp]+,r3\n" + "mov.l @%[patp]+,r6\n" + "mov.l @%[patp]+,r7\n" + "mov.l @%[patp]+,r8\n" + "mov.l @%[patp]+,r9\n" + "mov.l @%[patp]+,r10 \n" - "tst %4,%4 \n" /* nothing to keep? */ + "tst %[mask],%[mask] \n" /* nothing to keep? */ "bt .ur_sloop \n" /* yes: jump to short loop */ ".ur_floop: \n" /** full loop (there are bits to keep)**/ @@ -430,13 +426,13 @@ void gray_update_rect(int x, int y, int width, int height) "shlr r9 \n" "rotcl r0 \n" "shlr r10 \n" - "mov.b @%0,%3 \n" /* read old value */ + "mov.b @%[addr],%[patp]\n" /* read old value */ "rotcl r0 \n" - "and %4,%3 \n" /* mask out unneeded bits */ - "or r0,%3 \n" /* set new bits */ - "mov.b %3,@%0 \n" /* store value to bitplane */ - "add %2,%0 \n" /* advance to next bitplane */ - "cmp/hi %0,%1 \n" /* last bitplane done? */ + "and %[mask],%[patp] \n" /* mask out unneeded bits */ + "or %[patp],r0 \n" /* set new bits */ + "mov.b r0,@%[addr] \n" /* store value to bitplane */ + "add %[psiz],%[addr] \n" /* advance to next bitplane */ + "cmp/hi %[addr],%[end] \n" /* last bitplane done? */ "bt .ur_floop \n" /* no: loop */ "bra .ur_end \n" @@ -459,23 +455,184 @@ void gray_update_rect(int x, int y, int width, int height) "rotcl r0 \n" "shlr r10 \n" "rotcl r0 \n" - "mov.b r0,@%0 \n" /* store byte to bitplane */ - "add %2,%0 \n" /* advance to next bitplane */ - "cmp/hi %0,%1 \n" /* last bitplane done? */ + "mov.b r0,@%[addr] \n" /* store byte to bitplane */ + "add %[psiz],%[addr] \n" /* advance to next bitplane */ + "cmp/hi %[addr],%[end] \n" /* last bitplane done? */ "bt .ur_sloop \n" /* no: loop */ - ".ur_end: \n" + ".ur_end: \n" : /* outputs */ + [patp]"+r"(pat_ptr), + [addr]"+r"(addr), + [mask]"+r"(mask) : /* inputs */ - /* %0 */ "r"(dst_row), - /* %1 */ "r"(end_addr), - /* %2 */ "r"(_gray_info.plane_size), - /* %3 */ "r"(pat_ptr), - /* %4 */ "r"(mask) + [end] "r"(end), + [psiz]"r"(_gray_info.plane_size) : /* clobbers */ "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10" ); } +#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) + unsigned long pat_stack[4]; + unsigned long *pat_ptr; + unsigned change; + + asm volatile ( + "move.l (%[ofs]:l:1,%[cbuf]),%[chg] \n" + "sub.l (%[ofs]:l:1,%[bbuf]),%[chg] \n" + : /* outputs */ + [chg] "=&d"(change) + : /* inputs */ + [cbuf]"a"(_gray_info.cur_buffer), + [bbuf]"a"(_gray_info.back_buffer), + [ofs] "d"(srcofs_row) + ); + + if (change != 0) + { + unsigned char *cbuf, *bbuf, *addr, *end; + unsigned mask; + + pat_ptr = &pat_stack[4]; + cbuf = _gray_info.cur_buffer; + bbuf = _gray_info.back_buffer; + + /* precalculate the bit patterns with random shifts + * for all 4 pixels and put them on an extra "stack" */ + asm volatile ( + "add.l %[ofs],%[cbuf] \n" + "add.l %[ofs],%[bbuf] \n" + "moveq.l #4,%%d3 \n" /* loop count in d3: 4 pixels */ + "clr.l %[mask] \n" + + ".ur_pre_loop: \n" + "clr.l %%d0 \n" + "move.b (%[cbuf])+,%%d0 \n" /* read current buffer */ + "clr.l %%d1 \n" + "move.b (%[bbuf]),%%d1 \n" /* read back buffer */ + "move.b %%d0,(%[bbuf])+ \n" /* update back buffer */ + "clr.l %%d2 \n" /* preset for skipped pixel */ + "cmp.l %%d0,%%d1 \n" /* no change? */ + "beq.b .ur_skip \n" /* -> skip */ + + "move.l (%%d0:l:4,%[bpat]),%%d2 \n" /* d2 = bitpattern[byte]; */ + + "mulu.w #75,%[rnd] \n" /* multiply by 75 */ + "add.l #74,%[rnd] \n" /* add another 74 */ + /* Since the lower bits are not very random: */ + "move.l %[rnd],%%d1 \n" + "lsr.l #8,%%d1 \n" /* get bits 8..15 (need max. 5) */ + "and.l %[rmsk],%%d1\n" /* mask out unneeded bits */ + + "cmp.l %[dpth],%%d1\n" /* random >= depth ? */ + "blo.b .ur_ntrim \n" + "sub.l %[dpth],%%d1\n" /* yes: random -= depth; */ + ".ur_ntrim: \n" + + "move.l %%d2,%%d0 \n" + "lsl.l %%d1,%%d0 \n" + "sub.l %[dpth],%%d1\n" + "neg.l %%d1 \n" /* d1 = depth - d1 */ + "lsr.l %%d1,%%d2 \n" + "or.l %%d0,%%d2 \n" /* rotated_pattern = d2 | d0 */ + + "or.l #0x0300,%[mask] \n" /* set mask bit */ + + ".ur_skip: \n" + "lsr.l #2,%[mask] \n" /* shift mask */ + "move.l %%d2,-(%[patp]) \n" /* push on pattern stack */ + + "subq.l #1,%%d3 \n" /* decrease loop count */ + "bne.b .ur_pre_loop\n" /* yes: loop */ + : /* outputs */ + [cbuf]"+a"(cbuf), + [bbuf]"+a"(bbuf), + [patp]"+a"(pat_ptr), + [rnd] "+d"(_gray_random_buffer), + [mask]"=&d"(mask) + : /* inputs */ + [ofs] "[mask]"(srcofs_row), + [bpat]"a"(_gray_info.bitpattern), + [dpth]"d"(_gray_info.depth), + [rmsk]"d"(_gray_info.randmask) + : /* clobbers */ + "d0", "d1", "d2", "d3" + ); + + addr = dst_row; + end = addr + MULU16(_gray_info.depth, _gray_info.plane_size); + + /* set the bits for all 4 pixels in all bytes according to the + * precalculated patterns on the pattern stack */ + asm volatile ( + "movem.l (%[patp]),%%d2-%%d5 \n" /* pop all 4 patterns */ + + "not.l %[mask] \n" /* set mask -> keep mask */ + "and.l #0xFF,%[mask] \n" + "beq.b .ur_sloop \n" /* yes: jump to short loop */ + + ".ur_floop: \n" /** full loop (there are bits to keep)**/ + "clr.l %%d0 \n" + "lsr.l #1,%%d2 \n" /* shift out mask bit */ + "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */ + "lsl.l #1,%%d0 \n" /* shift by another 1 for a total of 2 */ + "lsr.l #1,%%d3 \n" + "addx.l %%d0,%%d0 \n" + "lsl.l #1,%%d0 \n" + "lsr.l #1,%%d4 \n" + "addx.l %%d0,%%d0 \n" + "lsl.l #1,%%d0 \n" + "lsr.l #1,%%d5 \n" + "addx.l %%d0,%%d0 \n" + "move.l %%d0,%%d1 \n" /* duplicate bits 0, 2, 4, 6, ... */ + "lsl.l #1,%%d1 \n" /* to 1, 3, 5, 7, ... */ + "or.l %%d1,%%d0 \n" + + "move.b (%[addr]),%%d1 \n" /* read old value */ + "and.l %[mask],%%d1 \n" /* mask out unneeded bits */ + "or.l %%d0,%%d1 \n" /* set new bits */ + "move.b %%d1,(%[addr]) \n" /* store value to bitplane */ + + "add.l %[psiz],%[addr] \n" /* advance to next bitplane */ + "cmp.l %[addr],%[end] \n" /* last bitplane done? */ + "bhi.b .ur_floop \n" /* no: loop */ + + "bra.b .ur_end \n" + + ".ur_sloop: \n" /** short loop (nothing to keep) **/ + "clr.l %%d0 \n" + "lsr.l #1,%%d2 \n" /* shift out mask bit */ + "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */ + "lsl.l #1,%%d0 \n" /* shift by another 1 for a total of 2 */ + "lsr.l #1,%%d3 \n" + "addx.l %%d0,%%d0 \n" + "lsl.l #1,%%d0 \n" + "lsr.l #1,%%d4 \n" + "addx.l %%d0,%%d0 \n" + "lsl.l #1,%%d0 \n" + "lsr.l #1,%%d5 \n" + "addx.l %%d0,%%d0 \n" + "move.l %%d0,%%d1 \n" /* duplicate bits 0, 2, 4, 6, ... */ + "lsl.l #1,%%d1 \n" /* to 1, 3, 5, 7, ... */ + "or.l %%d1,%%d0 \n" + + "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */ + "add.l %[psiz],%[addr] \n" /* advance to next bitplane */ + "cmp.l %[addr],%[end] \n" /* last bitplane done? */ + "bhi.b .ur_sloop \n" /* no: loop */ + + ".ur_end: \n" + : /* outputs */ + [addr]"+a"(addr), + [mask]"+d"(mask) + : /* inputs */ + [psiz]"r"(_gray_info.plane_size), + [end] "a"(end), + [patp]"a"(pat_ptr) + : /* clobbers */ + "d0", "d1", "d2", "d3", "d4", "d5" + ); + } #endif srcofs_row += _gray_info.height; dst_row++; @@ -517,7 +674,7 @@ void gray_deferred_lcd_update(void) /*** Screenshot ***/ -#define BMP_NUMCOLORS (_MAX_DEPTH * _LEVEL_FAC + 1) +#define BMP_NUMCOLORS 33 #define BMP_BPP 8 #define BMP_LINESIZE ((LCD_WIDTH + 3) & ~3) #define BMP_HEADERSIZE (54 + 4 * BMP_NUMCOLORS) @@ -564,9 +721,12 @@ static unsigned char linebuf[BMP_LINESIZE]; void gray_screendump(void) { int fh, i, bright; - int x, y, by, mask; + int y; +#if LCD_DEPTH == 1 + int x, by, mask; int gx, gby; unsigned char *lcdptr, *grayptr, *grayptr2; +#endif char filename[MAX_PATH]; #ifdef HAVE_RTC @@ -617,24 +777,24 @@ void gray_screendump(void) _gray_rb->write(fh, bmpheader, sizeof(bmpheader)); /* write header */ - /* build clut, always 33 entries */ + /* build clut */ linebuf[3] = 0; for (i = 0; i < BMP_NUMCOLORS; i++) { - bright = MIN(i, _LEVEL_FAC * _gray_info.depth); - linebuf[0] = MULU16(BMP_BLUE, bright) / (_LEVEL_FAC * _gray_info.depth); - linebuf[1] = MULU16(BMP_GREEN, bright) / (_LEVEL_FAC * _gray_info.depth); - linebuf[2] = MULU16(BMP_RED, bright) / (_LEVEL_FAC * _gray_info.depth); + bright = MIN(i, _gray_info.depth); + linebuf[0] = MULU16(BMP_BLUE, bright) / _gray_info.depth; + linebuf[1] = MULU16(BMP_GREEN, bright) / _gray_info.depth; + linebuf[2] = MULU16(BMP_RED, bright) / _gray_info.depth; _gray_rb->write(fh, linebuf, 4); } /* 8-bit BMP image goes bottom -> top */ for (y = LCD_HEIGHT - 1; y >= 0; y--) { -#if LCD_DEPTH == 1 _gray_rb->memset(linebuf, BMP_NUMCOLORS-1, LCD_WIDTH); +#if LCD_DEPTH == 1 mask = 1 << (y & 7); by = y >> 3; lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by); @@ -675,6 +835,8 @@ void gray_screendump(void) if (*lcdptr++ & mask) linebuf[x] = 0; } +#elif LCD_DEPTH == 2 + /* TODO */ #endif _gray_rb->write(fh, linebuf, sizeof(linebuf)); diff --git a/apps/plugins/lib/gray_draw.c b/apps/plugins/lib/gray_draw.c index 0742459d4b..ab1b286137 100644 --- a/apps/plugins/lib/gray_draw.c +++ b/apps/plugins/lib/gray_draw.c @@ -8,7 +8,7 @@ * $Id$ * * Greyscale framework -* Drawing functions for buffered mode +* Drawing functions * * This is a generic framework to use grayscale display within Rockbox * plugins. It obviously does not work for the player. @@ -43,7 +43,7 @@ static void clearpixel(unsigned char *address) static void flippixel(unsigned char *address) { - *address = _LEVEL_FAC * _gray_info.depth - *address; + *address = _gray_info.depth - *address; } static void nopixel(unsigned char *address) @@ -507,7 +507,7 @@ void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, dst_end = dst_col + height; do { - unsigned data = MULU16(_LEVEL_FAC * _gray_info.depth, *src_col) + 127; + unsigned data = MULU16(_gray_info.depth, *src_col) + 127; *dst_col++ = (data + (data >> 8)) >> 8; /* approx. data / 255 */ src_col += stride; } @@ -586,22 +586,26 @@ static void _writearray(unsigned char *address, const unsigned char *src, #if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) unsigned long pat_stack[8]; unsigned long *pat_ptr = &pat_stack[8]; - unsigned char *end_addr; + const unsigned char *_src; + unsigned char *addr, *end; + unsigned _mask; + + _mask = mask; + _src = src; /* precalculate the bit patterns with random shifts for all 8 pixels and put them on an extra "stack" */ - asm ( + asm volatile ( "mov #8,r3 \n" /* loop count in r3: 8 pixels */ - "mov %7,r2 \n" /* copy mask -- gcc bug workaround */ ".wa_loop: \n" /** load pattern for pixel **/ "mov #0,r0 \n" /* pattern for skipped pixel must be 0 */ - "shlr r2 \n" /* shift out lsb of mask */ + "shlr %[mask] \n" /* shift out lsb of mask */ "bf .wa_skip \n" /* skip this pixel */ - "mov.b @%2,r0 \n" /* load src byte */ + "mov.b @%[src],r0 \n" /* load src byte */ "extu.b r0,r0 \n" /* extend unsigned */ - "mulu %4,r0 \n" /* macl = byte * depth; */ + "mulu %[dpth],r0 \n" /* macl = byte * depth; */ "sts macl,r1 \n" /* r1 = macl; */ "add #127,r1 \n" /* byte += 127; */ "mov r1,r0 \n" @@ -609,26 +613,26 @@ static void _writearray(unsigned char *address, const unsigned char *src, "add r1,r0 \n" /* byte += byte >> 8; */ "shlr8 r0 \n" /* byte >>= 8; */ "shll2 r0 \n" - "mov.l @(r0,%5),r4 \n" /* r4 = bitpattern[byte]; */ + "mov.l @(r0,%[bpat]),r4\n" /* r4 = bitpattern[byte]; */ "mov #75,r0 \n" - "mulu r0,%0 \n" /* multiply by 75 */ - "sts macl,%0 \n" - "add #74,%0 \n" /* add another 74 */ + "mulu r0,%[rnd] \n" /* multiply by 75 */ + "sts macl,%[rnd] \n" + "add #74,%[rnd] \n" /* add another 74 */ /* Since the lower bits are not very random: */ - "swap.b %0,r1 \n" /* get bits 8..15 (need max. 5) */ - "and %6,r1 \n" /* mask out unneeded bits */ + "swap.b %[rnd],r1 \n" /* get bits 8..15 (need max. 5) */ + "and %[rmsk],r1 \n" /* mask out unneeded bits */ - "cmp/hs %4,r1 \n" /* random >= depth ? */ + "cmp/hs %[dpth],r1 \n" /* random >= depth ? */ "bf .wa_ntrim \n" - "sub %4,r1 \n" /* yes: random -= depth; */ + "sub %[dpth],r1 \n" /* yes: random -= depth; */ ".wa_ntrim: \n" "mov.l .ashlsi3,r0 \n" /** rotate pattern **/ "jsr @r0 \n" /* r4 -> r0, shift left by r5 */ "mov r1,r5 \n" - "mov %4,r5 \n" + "mov %[dpth],r5 \n" "sub r1,r5 \n" /* r5 = depth - r1 */ "mov.l .lshrsi3,r1 \n" "jsr @r1 \n" /* r4 -> r0, shift right by r5 */ @@ -637,43 +641,45 @@ static void _writearray(unsigned char *address, const unsigned char *src, "or r1,r0 \n" /* rotated_pattern = r0 | r1 */ ".wa_skip: \n" - "mov.l r0,@-%1 \n" /* push on pattern stack */ + "mov.l r0,@-%[patp]\n" /* push on pattern stack */ - "add %3,%2 \n" /* src += stride; */ + "add %[stri],%[src] \n" /* src += stride; */ "add #-1,r3 \n" /* decrease loop count */ "cmp/pl r3 \n" /* loop count > 0? */ "bt .wa_loop \n" /* yes: loop */ : /* outputs */ - /* %0, in & out */ "+r"(_gray_random_buffer), - /* %1, in & out */ "+r"(pat_ptr) + [src] "+r"(_src), + [rnd] "+r"(_gray_random_buffer), + [patp]"+r"(pat_ptr), + [mask]"+r"(_mask) : /* inputs */ - /* %2 */ "r"(src), - /* %3 */ "r"(stride), - /* %4 */ "r"(_gray_info.depth), - /* %5 */ "r"(_gray_info.bitpattern), - /* %6 */ "r"(_gray_info.randmask), - /* %7 */ "r"(mask) + [stri]"r"(stride), + [dpth]"r"(_gray_info.depth), + [bpat]"r"(_gray_info.bitpattern), + [rmsk]"r"(_gray_info.randmask) : /* clobbers */ - "r0", "r1", "r2", "r3", "r4", "r5", "macl", "pr" + "r0", "r1", "r3", "r4", "r5", "macl", "pr" ); - end_addr = address + MULU16(_gray_info.depth, _gray_info.plane_size); + addr = address; + end = addr + MULU16(_gray_info.depth, _gray_info.plane_size); + _mask = mask; /* set the bits for all 8 pixels in all bytes according to the * precalculated patterns on the pattern stack */ - asm ( - "mov.l @%3+,r1 \n" /* pop all 8 patterns */ - "mov.l @%3+,r2 \n" - "mov.l @%3+,r3 \n" - "mov.l @%3+,r8 \n" - "mov.l @%3+,r9 \n" - "mov.l @%3+,r10 \n" - "mov.l @%3+,r11 \n" - "mov.l @%3+,r12 \n" + asm volatile ( + "mov.l @%[patp]+,r1\n" /* pop all 8 patterns */ + "mov.l @%[patp]+,r2\n" + "mov.l @%[patp]+,r3\n" + "mov.l @%[patp]+,r6\n" + "mov.l @%[patp]+,r7\n" + "mov.l @%[patp]+,r8\n" + "mov.l @%[patp]+,r9\n" + "mov.l @%[patp]+,r10 \n" - "not %4,%4 \n" /* "set" mask -> "keep" mask */ - "extu.b %4,%4 \n" /* mask out high bits */ - "tst %4,%4 \n" /* nothing to keep? */ + "not %[mask],%[mask] \n" /* "set" mask -> "keep" mask */ + "extu.b %[mask],%[mask] \n" /* mask out high bits */ + "tst %[mask],%[mask] \n" /* nothing to keep? */ "bt .wa_sloop \n" /* yes: jump to short loop */ ".wa_floop: \n" /** full loop (there are bits to keep)**/ @@ -683,22 +689,22 @@ static void _writearray(unsigned char *address, const unsigned char *src, "rotcl r0 \n" "shlr r3 \n" "rotcl r0 \n" + "shlr r6 \n" + "rotcl r0 \n" + "shlr r7 \n" + "rotcl r0 \n" "shlr r8 \n" "rotcl r0 \n" "shlr r9 \n" "rotcl r0 \n" "shlr r10 \n" + "mov.b @%[addr],%[patp]\n" /* read old value */ "rotcl r0 \n" - "shlr r11 \n" - "rotcl r0 \n" - "shlr r12 \n" - "mov.b @%0,%3 \n" /* read old value */ - "rotcl r0 \n" - "and %4,%3 \n" /* mask out unneeded bits */ - "or r0,%3 \n" /* set new bits */ - "mov.b %3,@%0 \n" /* store value to bitplane */ - "add %2,%0 \n" /* advance to next bitplane */ - "cmp/hi %0,%1 \n" /* last bitplane done? */ + "and %[mask],%[patp] \n" /* mask out unneeded bits */ + "or %[patp],r0 \n" /* set new bits */ + "mov.b r0,@%[addr] \n" /* store value to bitplane */ + "add %[psiz],%[addr] \n" /* advance to next bitplane */ + "cmp/hi %[addr],%[end] \n" /* last bitplane done? */ "bt .wa_floop \n" /* no: loop */ "bra .wa_end \n" @@ -711,31 +717,174 @@ static void _writearray(unsigned char *address, const unsigned char *src, "rotcl r0 \n" "shlr r3 \n" "rotcl r0 \n" + "shlr r6 \n" + "rotcl r0 \n" + "shlr r7 \n" + "rotcl r0 \n" "shlr r8 \n" "rotcl r0 \n" "shlr r9 \n" "rotcl r0 \n" "shlr r10 \n" "rotcl r0 \n" - "shlr r11 \n" - "rotcl r0 \n" - "shlr r12 \n" - "rotcl r0 \n" - "mov.b r0,@%0 \n" /* store byte to bitplane */ - "add %2,%0 \n" /* advance to next bitplane */ - "cmp/hi %0,%1 \n" /* last bitplane done? */ + "mov.b r0,@%[addr] \n" /* store byte to bitplane */ + "add %[psiz],%[addr] \n" /* advance to next bitplane */ + "cmp/hi %[addr],%[end] \n" /* last bitplane done? */ "bt .wa_sloop \n" /* no: loop */ ".wa_end: \n" : /* outputs */ + [patp]"+r"(pat_ptr), + [addr]"+r"(addr), + [mask]"+r"(_mask) : /* inputs */ - /* %0 */ "r"(address), - /* %1 */ "r"(end_addr), - /* %2 */ "r"(_gray_info.plane_size), - /* %3 */ "r"(pat_ptr), - /* %4 */ "r"(mask) + [end] "r"(end), + [psiz]"r"(_gray_info.plane_size) : /* clobbers */ - "r0", "r1", "r2", "r3", "r8", "r9", "r10", "r11", "r12" + "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10" + ); +#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) + unsigned long pat_stack[8]; + unsigned long *pat_ptr = &pat_stack[8]; + const unsigned char *_src; + unsigned char *addr, *end; + unsigned _mask; + + _mask = mask; + _src = src; + + /* precalculate the bit patterns with random shifts + for all 4 pixels and put them on an extra "stack" */ + asm volatile ( + "moveq.l #4,%%d3 \n" /* loop count in d3: 4 pixels */ + + ".wa_loop: \n" /** load pattern for pixel **/ + "clr.l %%d2 \n" /* pattern for skipped pixel must be 0 */ + "lsr.l #2,%[mask] \n" /* shift out 2 lsbs of mask */ + "bcc.b .wa_skip \n" /* skip this pixel */ + + "clr.l %%d0 \n" + "move.b (%[src]),%%d0 \n" /* load src byte */ + "mulu.w %[dpth],%%d0\n" /* byte = byte * depth; */ + "add.l #127,%%d0 \n" /* byte += 127; */ + "move.l %%d0,%%d1 \n" + "lsr.l #8,%%d1 \n" + "add.l %%d1,%%d0 \n" /* byte += byte >> 8; */ + "lsr.l #8,%%d0 \n" /* byte >>= 8; */ + "move.l (%%d0:l:4,%[bpat]),%%d2\n" /* d2 = bitpattern[byte]; */ + + "mulu.w #75,%[rnd] \n" /* multiply by 75 */ + "add.l #74,%[rnd] \n" /* add another 74 */ + /* Since the lower bits are not very random: */ + "move.l %[rnd],%%d1 \n" + "lsr.l #8,%%d1 \n" /* get bits 8..15 (need max. 5) */ + "and.l %[rmsk],%%d1\n" /* mask out unneeded bits */ + + "cmp.l %[dpth],%%d1\n" /* random >= depth ? */ + "blo.b .wa_ntrim \n" + "sub.l %[dpth],%%d1\n" /* yes: random -= depth; */ + ".wa_ntrim: \n" + + "move.l %%d2,%%d0 \n" + "lsl.l %%d1,%%d0 \n" + "sub.l %[dpth],%%d1\n" + "neg.l %%d1 \n" /* d1 = depth - d1 */ + "lsr.l %%d1,%%d2 \n" + "or.l %%d0,%%d2 \n" + + ".wa_skip: \n" + "move.l %%d2,-(%[patp]) \n" /* push on pattern stack */ + + "add.l %[stri],%[src] \n" /* src += stride; */ + "subq.l #1,%%d3 \n" /* decrease loop count */ + "bne.b .wa_loop \n" /* yes: loop */ + : /* outputs */ + [src] "+a"(_src), + [patp]"+a"(pat_ptr), + [rnd] "+d"(_gray_random_buffer), + [mask]"+d"(_mask) + : /* inputs */ + [stri]"r"(stride), + [bpat]"a"(_gray_info.bitpattern), + [dpth]"d"(_gray_info.depth), + [rmsk]"d"(_gray_info.randmask) + : /* clobbers */ + "d0", "d1", "d2", "d3" + ); + + addr = address; + end = addr + MULU16(_gray_info.depth, _gray_info.plane_size); + _mask = mask; + + /* set the bits for all 4 pixels in all bytes according to the + * precalculated patterns on the pattern stack */ + asm volatile ( + "movem.l (%[patp]),%%d2-%%d5 \n" /* pop all 4 patterns */ + + "not.l %[mask] \n" /* "set" mask -> "keep" mask */ + "and.l #0xFF,%[mask] \n" + "beq.b .wa_sloop \n" /* yes: jump to short loop */ + + ".wa_floop: \n" /** full loop (there are bits to keep)**/ + "clr.l %%d0 \n" + "lsr.l #1,%%d2 \n" /* shift out mask bit */ + "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */ + "lsl.l #1,%%d0 \n" /* shift by another 1 for a total of 2 */ + "lsr.l #1,%%d3 \n" + "addx.l %%d0,%%d0 \n" + "lsl.l #1,%%d0 \n" + "lsr.l #1,%%d4 \n" + "addx.l %%d0,%%d0 \n" + "lsl.l #1,%%d0 \n" + "lsr.l #1,%%d5 \n" + "addx.l %%d0,%%d0 \n" + "move.l %%d0,%%d1 \n" /* duplicate bits 0, 2, 4, 6, ... */ + "lsl.l #1,%%d1 \n" /* to 1, 3, 5, 7, ... */ + "or.l %%d1,%%d0 \n" + + "move.b (%[addr]),%%d1 \n" /* read old value */ + "and.l %[mask],%%d1 \n" /* mask out unneeded bits */ + "or.l %%d0,%%d1 \n" /* set new bits */ + "move.b %%d1,(%[addr]) \n" /* store value to bitplane */ + + "add.l %[psiz],%[addr] \n" /* advance to next bitplane */ + "cmp.l %[addr],%[end] \n" /* last bitplane done? */ + "bhi.b .wa_floop \n" /* no: loop */ + + "bra.b .wa_end \n" + + ".wa_sloop: \n" /** short loop (nothing to keep) **/ + "clr.l %%d0 \n" + "lsr.l #1,%%d2 \n" /* shift out mask bit */ + "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */ + "lsl.l #1,%%d0 \n" /* shift by another 1 for a total of 2 */ + "lsr.l #1,%%d3 \n" + "addx.l %%d0,%%d0 \n" + "lsl.l #1,%%d0 \n" + "lsr.l #1,%%d4 \n" + "addx.l %%d0,%%d0 \n" + "lsl.l #1,%%d0 \n" + "lsr.l #1,%%d5 \n" + "addx.l %%d0,%%d0 \n" + "move.l %%d0,%%d1 \n" /* duplicate bits 0, 2, 4, 6, ... */ + "lsl.l #1,%%d1 \n" /* to 1, 3, 5, 7, ... */ + "or.l %%d1,%%d0 \n" + + "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */ + "add.l %[psiz],%[addr] \n" /* advance to next bitplane */ + "cmp.l %[addr],%[end] \n" /* last bitplane done? */ + "bhi.b .wa_sloop \n" /* no: loop */ + + ".wa_end: \n" + : /* outputs */ + [addr]"+a"(addr), + [mask]"+d"(_mask) + : /* inputs */ + [psiz]"r"(_gray_info.plane_size), + [end] "a"(end), + [patp]"a"(pat_ptr) + : /* clobbers */ + "d0", "d1", "d2", "d3", "d4", "d5" ); #endif } @@ -789,8 +938,8 @@ void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, + MULU16(_gray_info.width, y >> _PBLOCK_EXP); ny = height - 1 + shift; - mask = 0xFFu << shift; /* ATTN LCD_DEPTH == 2 */ - mask_bottom = 0xFFu >> (~ny & (_PBLOCK-1)); + mask = 0xFFu << (LCD_DEPTH * shift); + mask_bottom = 0xFFu >> (LCD_DEPTH * (~ny & (_PBLOCK-1))); for (; ny >= _PBLOCK; ny -= _PBLOCK) { diff --git a/apps/plugins/lib/gray_parm.c b/apps/plugins/lib/gray_parm.c index c66cc33339..a8c238a4eb 100644 --- a/apps/plugins/lib/gray_parm.c +++ b/apps/plugins/lib/gray_parm.c @@ -55,7 +55,7 @@ int gray_get_drawmode(void) /* Set the foreground shade for subsequent drawing operations */ void gray_set_foreground(int brightness) { - unsigned data = MULU16(_LEVEL_FAC * _gray_info.depth, brightness & 0xFF) + 127; + unsigned data = MULU16(_gray_info.depth, brightness & 0xFF) + 127; _gray_info.fg_brightness = (data + (data >> 8)) >> 8; /* approx. data / 255 */ } @@ -63,14 +63,14 @@ void gray_set_foreground(int brightness) /* Return the current foreground shade */ int gray_get_foreground(void) { - return (_gray_info.fg_brightness * 255 + ((_LEVEL_FAC * _gray_info.depth) >> 1)) - / (_LEVEL_FAC * _gray_info.depth); + return (_gray_info.fg_brightness * 255 + (_gray_info.depth >> 1)) + / _gray_info.depth; } /* Set the background shade for subsequent drawing operations */ void gray_set_background(int brightness) { - unsigned data = MULU16(_LEVEL_FAC * _gray_info.depth, brightness & 0xFF) + 127; + unsigned data = MULU16(_gray_info.depth, brightness & 0xFF) + 127; _gray_info.bg_brightness = (data + (data >> 8)) >> 8; /* approx. data / 255 */ } @@ -78,8 +78,8 @@ void gray_set_background(int brightness) /* Return the current background shade */ int gray_get_background(void) { - return (_gray_info.bg_brightness * 255 + ((_LEVEL_FAC * _gray_info.depth) >> 1)) - / (_LEVEL_FAC * _gray_info.depth); + return (_gray_info.bg_brightness * 255 + (_gray_info.depth >> 1)) + / _gray_info.depth; } /* Set draw mode, foreground and background shades at once */ diff --git a/apps/plugins/lib/gray_scroll.c b/apps/plugins/lib/gray_scroll.c index e4520e7649..701d26fc50 100644 --- a/apps/plugins/lib/gray_scroll.c +++ b/apps/plugins/lib/gray_scroll.c @@ -260,9 +260,9 @@ void gray_ub_scroll_up(int count) asm ( "mov #0,r6 \n" /* x = 0 */ "mova .su_shifttbl,r0 \n" /* calculate jump destination for */ - "mov.b @(r0,%5),%5 \n" /* shift amount from table */ + "mov.b @(r0,%[cnt]),%[cnt] \n" /* shift amount from table */ "bra .su_cloop \n" /* skip table */ - "add r0,%5 \n" + "add r0,%[cnt] \n" ".align 2 \n" ".su_shifttbl: \n" /* shift jump offset table */ @@ -276,7 +276,7 @@ void gray_ub_scroll_up(int count) ".byte .su_shift7 - .su_shifttbl \n" ".su_cloop: \n" /* repeat for every column */ - "mov %1,r2 \n" /* get start address */ + "mov %[addr],r2 \n" /* get start address */ "mov #0,r3 \n" /* current_plane = 0 */ ".su_oloop: \n" /* repeat for every bitplane */ @@ -285,12 +285,12 @@ void gray_ub_scroll_up(int count) "mov #0,r1 \n" /* fill with zero */ ".su_iloop: \n" /* repeat for all rows */ - "sub %2,r4 \n" /* address -= width */ + "sub %[wide],r4 \n" /* address -= width */ "mov.b @r4,r0 \n" /* get data byte */ "shll8 r1 \n" /* old data to 2nd byte */ "extu.b r0,r0 \n" /* extend unsigned */ "or r1,r0 \n" /* combine old data */ - "jmp @%5 \n" /* jump into shift "path" */ + "jmp @%[cnt] \n" /* jump into shift "path" */ "extu.b r0,r1 \n" /* store data for next round */ ".su_shift6: \n" /* shift right by 0..7 bits */ @@ -312,29 +312,77 @@ void gray_ub_scroll_up(int count) "mov.b r0,@r4 \n" /* store data */ "add #1,r5 \n" /* current_row++ */ - "cmp/hi r5,%3 \n" /* current_row < bheight - shift ? */ + "cmp/hi r5,%[rows] \n" /* current_row < bheight - shift ? */ "bt .su_iloop \n" - "add %4,r2 \n" /* start_address += plane_size */ + "add %[psiz],r2 \n" /* start_address += plane_size */ "add #1,r3 \n" /* current_plane++ */ - "cmp/hi r3,%0 \n" /* current_plane < depth ? */ + "cmp/hi r3,%[dpth] \n" /* current_plane < depth ? */ "bt .su_oloop \n" - "add #1,%1 \n" /* start_address++ */ + "add #1,%[addr] \n" /* start_address++ */ "add #1,r6 \n" /* x++ */ - "cmp/hi r6,%2 \n" /* x < width ? */ + "cmp/hi r6,%[wide] \n" /* x < width ? */ "bt .su_cloop \n" : /* outputs */ : /* inputs */ - /* %0 */ "r"(_gray_info.depth), - /* %1 */ "r"(_gray_info.plane_data + _gray_info.plane_size - blockshift), - /* %2 */ "r"(_gray_info.width), - /* %3 */ "r"(_gray_info.bheight - shift), - /* %4 */ "r"(_gray_info.plane_size), - /* %5 */ "r"(count) + [dpth]"r"(_gray_info.depth), + [addr]"r"(_gray_info.plane_data + _gray_info.plane_size - blockshift), + [wide]"r"(_gray_info.width), + [rows]"r"(_gray_info.bheight - shift), + [psiz]"r"(_gray_info.plane_size), + [cnt] "r"(count) : /* clobbers */ "r0", "r1", "r2", "r3", "r4", "r5", "r6" ); +#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) + /* scroll column by column to minimize flicker */ + asm ( + "move.l %[wide],%%d4\n" /* columns = width */ + "add.l %[cnt],%[cnt] \n" /* shift 2 bits per pixel */ + + ".su_cloop: \n" /* repeat for every column */ + "move.l %[addr],%%a0\n" /* get start address */ + "move.l %[dpth],%%d2\n" /* planes = depth */ + + ".su_oloop: \n" /* repeat for every bitplane */ + "move.l %%a0,%%a1 \n" /* get start address */ + "move.l %[rows],%%d3\n" /* rows = row_count */ + "clr.l %%d1 \n" /* fill with zero */ + + ".su_iloop: \n" /* repeat for all rows */ + "sub.l %[wide],%%a1\n" /* address -= width */ + + "clr.l %%d0 \n" + "move.b (%%a1),%%d0 \n" /* get data byte */ + "lsl.l #8,%%d1 \n" /* old data to 2nd byte */ + "or.l %%d1,%%d0 \n" /* combine old data */ + "clr.l %%d1 \n" + "move.b %%d0,%%d1 \n" /* keep data for next round */ + "lsr.l %[cnt],%%d0 \n" /* shift right */ + "move.b %%d0,(%%a1) \n" /* store data */ + + "subq.l #1,%%d3 \n" /* rows-- */ + "bne.b .su_iloop \n" + + "add.l %[psiz],%%a0\n" /* start_address += plane_size */ + "subq.l #1,%%d2 \n" /* planes-- */ + "bne.b .su_oloop \n" + + "lea.l (1,%[addr]),%[addr] \n" /* start_address++ */ + "subq.l #1,%%d4 \n" /* columns-- */ + "bne.b .su_cloop \n" + : /* outputs */ + : /* inputs */ + [psiz]"r"(_gray_info.plane_size), + [dpth]"r"(_gray_info.depth), + [wide]"r"(_gray_info.width), + [rows]"r"(_gray_info.bheight - shift), + [addr]"a"(_gray_info.plane_data + _gray_info.plane_size - blockshift), + [cnt] "d"(count) + : /* clobbers */ + "a0", "a1", "d0", "d1", "d2", "d3", "d4" + ); #endif } } @@ -396,9 +444,9 @@ void gray_ub_scroll_down(int count) asm ( "mov #0,r6 \n" /* x = 0 */ "mova .sd_shifttbl,r0 \n" /* calculate jump destination for */ - "mov.b @(r0,%5),%5 \n" /* shift amount from table */ + "mov.b @(r0,%[cnt]),%[cnt] \n" /* shift amount from table */ "bra .sd_cloop \n" /* skip table */ - "add r0,%5 \n" + "add r0,%[cnt] \n" ".align 2 \n" ".sd_shifttbl: \n" /* shift jump offset table */ @@ -412,7 +460,7 @@ void gray_ub_scroll_down(int count) ".byte .sd_shift7 - .sd_shifttbl \n" ".sd_cloop: \n" /* repeat for every column */ - "mov %1,r2 \n" /* get start address */ + "mov %[addr],r2 \n" /* get start address */ "mov #0,r3 \n" /* current_plane = 0 */ ".sd_oloop: \n" /* repeat for every bitplane */ @@ -423,7 +471,7 @@ void gray_ub_scroll_down(int count) ".sd_iloop: \n" /* repeat for all rows */ "shlr8 r1 \n" /* shift right to get residue */ "mov.b @r4,r0 \n" /* get data byte */ - "jmp @%5 \n" /* jump into shift "path" */ + "jmp @%[cnt] \n" /* jump into shift "path" */ "extu.b r0,r0 \n" /* extend unsigned */ ".sd_shift6: \n" /* shift left by 0..7 bits */ @@ -445,31 +493,76 @@ void gray_ub_scroll_down(int count) "or r0,r1 \n" /* combine with last residue */ "mov.b r1,@r4 \n" /* store data */ - "add %2,r4 \n" /* address += width */ + "add %[wide],r4 \n" /* address += width */ "add #1,r5 \n" /* current_row++ */ - "cmp/hi r5,%3 \n" /* current_row < bheight - shift ? */ + "cmp/hi r5,%[rows] \n" /* current_row < bheight - shift ? */ "bt .sd_iloop \n" - "add %4,r2 \n" /* start_address += plane_size */ + "add %[psiz],r2 \n" /* start_address += plane_size */ "add #1,r3 \n" /* current_plane++ */ - "cmp/hi r3,%0 \n" /* current_plane < depth ? */ + "cmp/hi r3,%[dpth] \n" /* current_plane < depth ? */ "bt .sd_oloop \n" - "add #1,%1 \n" /* start_address++ */ + "add #1,%[addr] \n" /* start_address++ */ "add #1,r6 \n" /* x++ */ - "cmp/hi r6,%2 \n" /* x < width ? */ + "cmp/hi r6,%[wide] \n" /* x < width ? */ "bt .sd_cloop \n" : /* outputs */ : /* inputs */ - /* %0 */ "r"(_gray_info.depth), - /* %1 */ "r"(_gray_info.plane_data + blockshift), - /* %2 */ "r"(_gray_info.width), - /* %3 */ "r"(_gray_info.bheight - shift), - /* %4 */ "r"(_gray_info.plane_size), - /* %5 */ "r"(count) + [dpth]"r"(_gray_info.depth), + [addr]"r"(_gray_info.plane_data + blockshift), + [wide]"r"(_gray_info.width), + [rows]"r"(_gray_info.bheight - shift), + [psiz]"r"(_gray_info.plane_size), + [cnt] "r"(count) : /* clobbers */ "r0", "r1", "r2", "r3", "r4", "r5", "r6" ); +#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) + /* scroll column by column to minimize flicker */ + asm ( + "move.l %[wide],%%d4\n" /* columns = width */ + "add.l %[cnt],%[cnt] \n" /* shift 2 bits per pixel */ + + ".sd_cloop: \n" /* repeat for every column */ + "move.l %[addr],%%a0\n" /* get start address */ + "move.l %[dpth],%%d2\n" /* planes = depth */ + + ".sd_oloop: \n" /* repeat for every bitplane */ + "move.l %%a0,%%a1 \n" /* get start address */ + "move.l %[rows],%%d3\n" /* rows = row_count */ + "clr.l %%d1 \n" /* fill with zero */ + + ".sd_iloop: \n" /* repeat for all rows */ + "lsr.l #8,%%d1 \n" /* shift right to get residue */ + "clr.l %%d0 \n" + "move.b (%%a1),%%d0 \n" /* get data byte */ + "lsl.l %[cnt],%%d0 \n" + "or.l %%d0,%%d1 \n" /* combine with last residue */ + "move.b %%d1,(%%a1) \n" /* store data */ + + "add.l %[wide],%%a1\n" /* address += width */ + "subq.l #1,%%d3 \n" /* rows-- */ + "bne.b .sd_iloop \n" + + "add.l %[psiz],%%a0\n" /* start_address += plane_size */ + "subq.l #1,%%d2 \n" /* planes-- */ + "bne.b .sd_oloop \n" + + "lea.l (1,%[addr]),%[addr] \n" /* start_address++ */ + "subq.l #1,%%d4 \n" /* columns-- */ + "bne.b .sd_cloop \n" + : /* outputs */ + : /* inputs */ + [dpth]"r"(_gray_info.depth), + [wide]"r"(_gray_info.width), + [rows]"r"(_gray_info.bheight - shift), + [psiz]"r"(_gray_info.plane_size), + [addr]"a"(_gray_info.plane_data + blockshift), + [cnt] "d"(count) + : /* clobbers */ + "a0", "a1", "d0", "d1", "d2", "d3", "d4" + ); #endif } }