1
0
Fork 0
forked from len0rd/rockbox

Grayscale library: (1) Ported to iriver H1x0. Experiments have shown that the intended 49-shade mode isn't possible due to interference between the internal greylevel generation of the LCD and external pixel flipping, so the lib allows 33 shades as on the Archos. The current implementation wastes RAM by not switching the LCD to b&w mode and simply using colours 0 and 3 only. However, this allows to show a partial greyscale overlay and normal 4-shade graphics in parallel. (2) Converted all asm blocks to use symbolic parameters. (3) Properly marked asm input parameters that are changed within the block as in-out and feed them from a temp variable where necessary. (4) Screenshot is not yet working on H1x0.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7244 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2005-07-27 19:58:49 +00:00
parent 988ea2cffc
commit 00866dbf86
6 changed files with 618 additions and 216 deletions

View file

@ -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

View file

@ -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 */

View file

@ -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,8 +166,7 @@ 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;
@ -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"
: /* 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));

View file

@ -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)
{

View file

@ -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 */

View file

@ -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
}
}