mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-19 01:52:35 -05:00
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:
parent
a4f39a6361
commit
9ca74798b6
1 changed files with 83 additions and 74 deletions
|
|
@ -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,36 +660,39 @@ 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... */
|
||||||
".sl_loop1: \n"
|
"or %2,r1 \n" /* ...and offset are even */
|
||||||
"mov.b @%0+,r1 \n"
|
"shlr r1 \n" /* -> lsb = 0 */
|
||||||
"mov.b r1,@(%2,%0) \n"
|
"bf .sl_start2 \n" /* -> copy word-wise */
|
||||||
"cmp/hi %0,%1 \n"
|
|
||||||
"bt .sl_loop1 \n"
|
"add #-1,%2 \n" /* copy byte-wise */
|
||||||
: /* outputs */
|
".sl_loop1: \n"
|
||||||
: /* inputs */
|
"mov.b @%0+,r1 \n"
|
||||||
/* %0 */ "r"(ptr + count),
|
"mov.b r1,@(%2,%0) \n"
|
||||||
/* %1 */ "r"(ptr + graybuf->width),
|
"cmp/hi %0,%1 \n"
|
||||||
/* %2 */ "z"(-count - 1)
|
"bt .sl_loop1 \n"
|
||||||
: /* clobbers */
|
|
||||||
"r1"
|
"bra .sl_end \n"
|
||||||
);
|
"nop \n"
|
||||||
else /* even count: scroll word-wise */
|
|
||||||
asm volatile (
|
".sl_start2: \n" /* copy word-wise */
|
||||||
".sl_loop2: \n"
|
"add #-2,%2 \n"
|
||||||
"mov.w @%0+,r1 \n"
|
".sl_loop2: \n"
|
||||||
"mov.w r1,@(%2,%0) \n"
|
"mov.w @%0+,r1 \n"
|
||||||
"cmp/hi %0,%1 \n"
|
"mov.w r1,@(%2,%0) \n"
|
||||||
"bt .sl_loop2 \n"
|
"cmp/hi %0,%1 \n"
|
||||||
: /* outputs */
|
"bt .sl_loop2 \n"
|
||||||
: /* inputs */
|
|
||||||
/* %0 */ "r"(ptr + count),
|
".sl_end: \n"
|
||||||
/* %1 */ "r"(ptr + graybuf->width),
|
: /* outputs */
|
||||||
/* %2 */ "z"(-count - 2)
|
: /* inputs */
|
||||||
: /* clobbers */
|
/* %0 */ "r"(ptr + count),
|
||||||
"r1"
|
/* %1 */ "r"(ptr + graybuf->width),
|
||||||
);
|
/* %2 */ "z"(-count)
|
||||||
|
: /* clobbers */
|
||||||
|
"r1"
|
||||||
|
);
|
||||||
|
|
||||||
rb->memset(ptr + graybuf->width - count, filler, count);
|
rb->memset(ptr + graybuf->width - count, filler, count);
|
||||||
ptr += graybuf->plane_size;
|
ptr += graybuf->plane_size;
|
||||||
|
|
@ -725,36 +728,39 @@ 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... */
|
||||||
".sr_loop1: \n"
|
"or %2,r1 \n" /* ...and offset are even */
|
||||||
"mov.b @(%2,%0),r1 \n"
|
"shlr r1 \n" /* -> lsb = 0 */
|
||||||
"mov.b r1,@-%0 \n"
|
"bf .sr_start2 \n" /* -> copy word-wise */
|
||||||
"cmp/hi %1,%0 \n"
|
|
||||||
"bt .sr_loop1 \n"
|
"add #-1,%2 \n" /* copy byte-wise */
|
||||||
: /* outputs */
|
".sr_loop1: \n"
|
||||||
: /* inputs */
|
"mov.b @(%2,%0),r1 \n"
|
||||||
/* %0 */ "r"(ptr + graybuf->width),
|
"mov.b r1,@-%0 \n"
|
||||||
/* %1 */ "r"(ptr + count),
|
"cmp/hi %1,%0 \n"
|
||||||
/* %2 */ "z"(-count - 1)
|
"bt .sr_loop1 \n"
|
||||||
: /* clobbers */
|
|
||||||
"r1"
|
"bra .sr_end \n"
|
||||||
);
|
"nop \n"
|
||||||
else /* even count: scroll word-wise */
|
|
||||||
asm volatile (
|
".sr_start2: \n" /* copy word-wise */
|
||||||
".sr_loop2: \n"
|
"add #-2,%2 \n"
|
||||||
"mov.w @(%2,%0),r1 \n"
|
".sr_loop2: \n"
|
||||||
"mov.w r1,@-%0 \n"
|
"mov.w @(%2,%0),r1 \n"
|
||||||
"cmp/hi %1,%0 \n"
|
"mov.w r1,@-%0 \n"
|
||||||
"bt .sr_loop2 \n"
|
"cmp/hi %1,%0 \n"
|
||||||
: /* outputs */
|
"bt .sr_loop2 \n"
|
||||||
: /* inputs */
|
|
||||||
/* %0 */ "r"(ptr + graybuf->width),
|
".sr_end: \n"
|
||||||
/* %1 */ "r"(ptr + count),
|
: /* outputs */
|
||||||
/* %2 */ "z"(-count - 2)
|
: /* inputs */
|
||||||
: /* clobbers */
|
/* %0 */ "r"(ptr + graybuf->width),
|
||||||
"r1"
|
/* %1 */ "r"(ptr + count),
|
||||||
);
|
/* %2 */ "z"(-count)
|
||||||
|
: /* clobbers */
|
||||||
|
"r1"
|
||||||
|
);
|
||||||
|
|
||||||
rb->memset(ptr, filler, count);
|
rb->memset(ptr, filler, count);
|
||||||
ptr += graybuf->plane_size;
|
ptr += graybuf->plane_size;
|
||||||
|
|
@ -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,8 +1617,9 @@ 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);
|
||||||
x += width;
|
x += width;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue