Fix: scrolling left/right with even pixel counts caused an address error if the buffer width was odd. Some more tweaks and cleanups.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4681 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2004-05-21 20:48:35 +00:00
parent a4f39a6361
commit 9ca74798b6

View file

@ -77,7 +77,7 @@ static void gray_timer_isr(void)
int x1 = MAX(graybuf->x, 0); int x1 = MAX(graybuf->x, 0);
int x2 = MIN(graybuf->x + graybuf->width, LCD_WIDTH); int x2 = MIN(graybuf->x + graybuf->width, LCD_WIDTH);
int y1 = MAX(graybuf->by << 3, 0); int y1 = MAX(graybuf->by << 3, 0);
int y2 = MIN((graybuf->by + graybuf->bheight) << 3, LCD_HEIGHT); int y2 = MIN((graybuf->by << 3) + graybuf->height, LCD_HEIGHT);
if (y1 > 0) /* refresh part above overlay, full width */ if (y1 > 0) /* refresh part above overlay, full width */
rb->lcd_update_rect(0, 0, LCD_WIDTH, y1); rb->lcd_update_rect(0, 0, LCD_WIDTH, y1);
@ -108,7 +108,7 @@ static void graypixel(int x, int y, unsigned long pattern)
* It delivers max. 16 pseudo-random bits in each iteration. */ * It delivers max. 16 pseudo-random bits in each iteration. */
/* simple but fast pseudo-random generator */ /* simple but fast pseudo-random generator */
asm( asm (
"mov #75,r1 \n" "mov #75,r1 \n"
"mulu %1,r1 \n" /* multiply by 75 */ "mulu %1,r1 \n" /* multiply by 75 */
"sts macl,%1 \n" /* get result */ "sts macl,%1 \n" /* get result */
@ -126,7 +126,7 @@ static void graypixel(int x, int y, unsigned long pattern)
); );
/* precalculate mask and byte address in first bitplane */ /* precalculate mask and byte address in first bitplane */
asm( asm (
"mov %3,%0 \n" /* take y as base for address offset */ "mov %3,%0 \n" /* take y as base for address offset */
"shlr2 %0 \n" /* shift right by 3 (= divide by 8) */ "shlr2 %0 \n" /* shift right by 3 (= divide by 8) */
"shlr %0 \n" "shlr %0 \n"
@ -164,7 +164,7 @@ static void graypixel(int x, int y, unsigned long pattern)
); );
/* the hard part: set bits in all bitplanes according to pattern */ /* the hard part: set bits in all bitplanes according to pattern */
asm( asm volatile (
"cmp/hs %1,%5 \n" /* random >= depth ? */ "cmp/hs %1,%5 \n" /* random >= depth ? */
"bf .p_ntrim \n" "bf .p_ntrim \n"
"sub %1,%5 \n" /* yes: random -= depth */ "sub %1,%5 \n" /* yes: random -= depth */
@ -240,7 +240,7 @@ static void grayblock(int x, int by, unsigned char* src, int stride)
/* precalculate the bit patterns with random shifts (same RNG as graypixel, /* precalculate the bit patterns with random shifts (same RNG as graypixel,
* see there for an explanation) for all 8 pixels and put them on an * see there for an explanation) for all 8 pixels and put them on an
* extra stack */ * extra stack */
asm( asm (
"mova .gb_reload,r0 \n" /* set default loopback address */ "mova .gb_reload,r0 \n" /* set default loopback address */
"tst %3,%3 \n" /* stride == 0 ? */ "tst %3,%3 \n" /* stride == 0 ? */
"bf .gb_needreload \n" /* no: keep that address */ "bf .gb_needreload \n" /* no: keep that address */
@ -323,7 +323,7 @@ static void grayblock(int x, int by, unsigned char* src, int stride)
/* set the bits for all 8 pixels in all bytes according to the /* set the bits for all 8 pixels in all bytes according to the
* precalculated patterns on the pattern stack */ * precalculated patterns on the pattern stack */
asm ( asm volatile (
"mov.l @%3+,r1 \n" /* pop all 8 patterns */ "mov.l @%3+,r1 \n" /* pop all 8 patterns */
"mov.l @%3+,r2 \n" "mov.l @%3+,r2 \n"
"mov.l @%3+,r3 \n" "mov.l @%3+,r3 \n"
@ -368,7 +368,7 @@ static void grayblock(int x, int by, unsigned char* src, int stride)
/* Invert the bits for 1-8 pixels within the buffer */ /* Invert the bits for 1-8 pixels within the buffer */
static void grayinvertmasked(int x, int by, unsigned char mask) static void grayinvertmasked(int x, int by, unsigned char mask)
{ {
asm( asm volatile (
"mulu %4,%5 \n" /* width * by (offset of row) */ "mulu %4,%5 \n" /* width * by (offset of row) */
"mov #0,r1 \n" /* current_plane = 0 */ "mov #0,r1 \n" /* current_plane = 0 */
"sts macl,r2 \n" /* get mulu result */ "sts macl,r2 \n" /* get mulu result */
@ -473,7 +473,7 @@ int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width,
graybuf->data = (unsigned char *) (graybuf->bitpattern + depth + 1); graybuf->data = (unsigned char *) (graybuf->bitpattern + depth + 1);
graybuf->curfont = FONT_SYSFIXED; graybuf->curfont = FONT_SYSFIXED;
i = depth; i = depth - 1;
j = 8; j = 8;
while (i != 0) while (i != 0)
{ {
@ -660,33 +660,36 @@ void gray_scroll_left(int count, bool black_border)
ptr = graybuf->data + MULU16(graybuf->width, by); ptr = graybuf->data + MULU16(graybuf->width, by);
for (d = 0; d < graybuf->depth; d++) for (d = 0; d < graybuf->depth; d++)
{ {
if (count & 1) /* odd count: scroll byte-wise */
asm volatile ( asm volatile (
"mov %0,r1 \n" /* check if both source... */
"or %2,r1 \n" /* ...and offset are even */
"shlr r1 \n" /* -> lsb = 0 */
"bf .sl_start2 \n" /* -> copy word-wise */
"add #-1,%2 \n" /* copy byte-wise */
".sl_loop1: \n" ".sl_loop1: \n"
"mov.b @%0+,r1 \n" "mov.b @%0+,r1 \n"
"mov.b r1,@(%2,%0) \n" "mov.b r1,@(%2,%0) \n"
"cmp/hi %0,%1 \n" "cmp/hi %0,%1 \n"
"bt .sl_loop1 \n" "bt .sl_loop1 \n"
: /* outputs */
: /* inputs */ "bra .sl_end \n"
/* %0 */ "r"(ptr + count), "nop \n"
/* %1 */ "r"(ptr + graybuf->width),
/* %2 */ "z"(-count - 1) ".sl_start2: \n" /* copy word-wise */
: /* clobbers */ "add #-2,%2 \n"
"r1"
);
else /* even count: scroll word-wise */
asm volatile (
".sl_loop2: \n" ".sl_loop2: \n"
"mov.w @%0+,r1 \n" "mov.w @%0+,r1 \n"
"mov.w r1,@(%2,%0) \n" "mov.w r1,@(%2,%0) \n"
"cmp/hi %0,%1 \n" "cmp/hi %0,%1 \n"
"bt .sl_loop2 \n" "bt .sl_loop2 \n"
".sl_end: \n"
: /* outputs */ : /* outputs */
: /* inputs */ : /* inputs */
/* %0 */ "r"(ptr + count), /* %0 */ "r"(ptr + count),
/* %1 */ "r"(ptr + graybuf->width), /* %1 */ "r"(ptr + graybuf->width),
/* %2 */ "z"(-count - 2) /* %2 */ "z"(-count)
: /* clobbers */ : /* clobbers */
"r1" "r1"
); );
@ -725,33 +728,36 @@ void gray_scroll_right(int count, bool black_border)
ptr = graybuf->data + MULU16(graybuf->width, by); ptr = graybuf->data + MULU16(graybuf->width, by);
for (d = 0; d < graybuf->depth; d++) for (d = 0; d < graybuf->depth; d++)
{ {
if (count & 1) /* odd count: scroll byte-wise */
asm volatile ( asm volatile (
"mov %0,r1 \n" /* check if both source... */
"or %2,r1 \n" /* ...and offset are even */
"shlr r1 \n" /* -> lsb = 0 */
"bf .sr_start2 \n" /* -> copy word-wise */
"add #-1,%2 \n" /* copy byte-wise */
".sr_loop1: \n" ".sr_loop1: \n"
"mov.b @(%2,%0),r1 \n" "mov.b @(%2,%0),r1 \n"
"mov.b r1,@-%0 \n" "mov.b r1,@-%0 \n"
"cmp/hi %1,%0 \n" "cmp/hi %1,%0 \n"
"bt .sr_loop1 \n" "bt .sr_loop1 \n"
: /* outputs */
: /* inputs */ "bra .sr_end \n"
/* %0 */ "r"(ptr + graybuf->width), "nop \n"
/* %1 */ "r"(ptr + count),
/* %2 */ "z"(-count - 1) ".sr_start2: \n" /* copy word-wise */
: /* clobbers */ "add #-2,%2 \n"
"r1"
);
else /* even count: scroll word-wise */
asm volatile (
".sr_loop2: \n" ".sr_loop2: \n"
"mov.w @(%2,%0),r1 \n" "mov.w @(%2,%0),r1 \n"
"mov.w r1,@-%0 \n" "mov.w r1,@-%0 \n"
"cmp/hi %1,%0 \n" "cmp/hi %1,%0 \n"
"bt .sr_loop2 \n" "bt .sr_loop2 \n"
".sr_end: \n"
: /* outputs */ : /* outputs */
: /* inputs */ : /* inputs */
/* %0 */ "r"(ptr + graybuf->width), /* %0 */ "r"(ptr + graybuf->width),
/* %1 */ "r"(ptr + count), /* %1 */ "r"(ptr + count),
/* %2 */ "z"(-count - 2) /* %2 */ "z"(-count)
: /* clobbers */ : /* clobbers */
"r1" "r1"
); );
@ -864,7 +870,7 @@ void gray_scroll_up(int count, bool black_border)
filler = 0; filler = 0;
/* scroll column by column to minimize flicker */ /* scroll column by column to minimize flicker */
asm( asm volatile (
"mov #0,r6 \n" /* x = 0 */ "mov #0,r6 \n" /* x = 0 */
"mova .su_shifttbl,r0 \n" /* calculate jump destination for */ "mova .su_shifttbl,r0 \n" /* calculate jump destination for */
"mov.b @(r0,%6),%6 \n" /* shift amount from table */ "mov.b @(r0,%6),%6 \n" /* shift amount from table */
@ -967,7 +973,7 @@ void gray_scroll_down(int count, bool black_border)
filler = 0; filler = 0;
/* scroll column by column to minimize flicker */ /* scroll column by column to minimize flicker */
asm( asm volatile (
"mov #0,r6 \n" /* x = 0 */ "mov #0,r6 \n" /* x = 0 */
"mova .sd_shifttbl,r0 \n" /* calculate jump destination for */ "mova .sd_shifttbl,r0 \n" /* calculate jump destination for */
"mov.b @(r0,%6),%6 \n" /* shift amount from table */ "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)
void gray_drawgraymap(unsigned char *src, int x, int y, int nx, int ny, void gray_drawgraymap(unsigned char *src, int x, int y, int nx, int ny,
int stride) int stride)
{ {
int xi, yi; int xi, yi, byte;
unsigned char *row; unsigned char *row;
if (graybuf == NULL if (graybuf == NULL
@ -1464,7 +1470,9 @@ void gray_drawgraymap(unsigned char *src, int x, int y, int nx, int ny,
{ {
for (xi = x; xi < x + nx; xi++) for (xi = x; xi < x + nx; xi++)
{ {
graypixel(xi, yi, graybuf->bitpattern[MULU16(*row++, byte = *row++;
/* separated to force GCC to use 16bit multiplication below */
graypixel(xi, yi, graybuf->bitpattern[MULU16(byte,
graybuf->depth + 1) >> 8]); graybuf->depth + 1) >> 8]);
} }
yi++; yi++;
@ -1609,7 +1617,8 @@ void gray_putsxy(int x, int y, unsigned char *str, bool draw_bg,
/* get proportional width and glyph bits */ /* get proportional width and glyph bits */
width = pf->width ? pf->width[ch] : pf->maxwidth; width = pf->width ? pf->width[ch] : pf->maxwidth;
bits = pf->bits + (pf->offset ? pf->offset[ch] : (pf->height * ch)); bits = pf->bits + (pf->offset ? pf->offset[ch]
: MULU16(pf->height, ch));
gray_drawbitmap((unsigned char*) bits, x, y, width, pf->height, gray_drawbitmap((unsigned char*) bits, x, y, width, pf->height,
width, draw_bg, fg_brightness, bg_brightness); width, draw_bg, fg_brightness, bg_brightness);