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:
parent
988ea2cffc
commit
00866dbf86
6 changed files with 618 additions and 216 deletions
|
@ -1,6 +1,6 @@
|
||||||
configfile.c
|
configfile.c
|
||||||
highscore.c
|
highscore.c
|
||||||
#if (CONFIG_LCD == LCD_SSD1815) && !defined(SIMULATOR)
|
#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) && !defined(SIMULATOR)
|
||||||
gray_core.c
|
gray_core.c
|
||||||
gray_draw.c
|
gray_draw.c
|
||||||
gray_parm.c
|
gray_parm.c
|
||||||
|
|
|
@ -113,8 +113,6 @@ void gray_ub_scroll_down(int count);
|
||||||
#define _PBLOCK_EXP 2
|
#define _PBLOCK_EXP 2
|
||||||
#endif
|
#endif
|
||||||
#define _PBLOCK (1 << _PBLOCK_EXP)
|
#define _PBLOCK (1 << _PBLOCK_EXP)
|
||||||
#define _MAX_DEPTH (32 / LCD_DEPTH)
|
|
||||||
#define _LEVEL_FAC ((1 << LCD_DEPTH) - 1)
|
|
||||||
|
|
||||||
/* flag definitions */
|
/* flag definitions */
|
||||||
#define _GRAY_RUNNING 0x0001 /* greyscale overlay is running */
|
#define _GRAY_RUNNING 0x0001 /* greyscale overlay is running */
|
||||||
|
|
|
@ -146,12 +146,12 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
|
||||||
|
|
||||||
plane_size = MULU16(width, bheight);
|
plane_size = MULU16(width, bheight);
|
||||||
possible_depth = (gbuf_size - buftaken - sizeof(long))
|
possible_depth = (gbuf_size - buftaken - sizeof(long))
|
||||||
/ (plane_size + _LEVEL_FAC * sizeof(long));
|
/ (plane_size + sizeof(long));
|
||||||
|
|
||||||
if (possible_depth < 1)
|
if (possible_depth < 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
depth = MIN(depth, _MAX_DEPTH);
|
depth = MIN(depth, 32);
|
||||||
depth = MIN(depth, possible_depth);
|
depth = MIN(depth, possible_depth);
|
||||||
|
|
||||||
_gray_info.x = 0;
|
_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;
|
_gray_info.plane_data = gbuf;
|
||||||
gbuf += depth * plane_size;
|
gbuf += depth * plane_size;
|
||||||
_gray_info.bitpattern = (unsigned long *)gbuf;
|
_gray_info.bitpattern = (unsigned long *)gbuf;
|
||||||
buftaken += depth * plane_size
|
buftaken += depth * plane_size + (depth + 1) * sizeof(long);
|
||||||
+ (_LEVEL_FAC * depth + 1) * sizeof(long);
|
|
||||||
|
|
||||||
i = depth - 1;
|
i = depth - 1;
|
||||||
j = 8;
|
j = 8;
|
||||||
while (i != 0)
|
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;
|
_gray_info.randmask = 0xFFu >> j;
|
||||||
|
|
||||||
/* Precalculate the bit patterns for all possible pixel values */
|
/* Precalculate the bit patterns for all possible pixel values */
|
||||||
#if LCD_DEPTH == 1
|
|
||||||
for (i = 0; i <= depth; i++)
|
for (i = 0; i <= depth; i++)
|
||||||
{
|
{
|
||||||
unsigned long pattern = 0;
|
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;
|
_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.fg_brightness = 0;
|
||||||
_gray_info.bg_brightness = _LEVEL_FAC * depth;
|
_gray_info.bg_brightness = depth;
|
||||||
_gray_info.drawmode = DRMODE_SOLID;
|
_gray_info.drawmode = DRMODE_SOLID;
|
||||||
_gray_info.curfont = FONT_SYSFIXED;
|
_gray_info.curfont = FONT_SYSFIXED;
|
||||||
|
|
||||||
|
@ -254,6 +228,7 @@ void gray_release(void)
|
||||||
lcd_set_invert_display(), lcd_set_flip(), lcd_roll() */
|
lcd_set_invert_display(), lcd_set_flip(), lcd_roll() */
|
||||||
void gray_show(bool enable)
|
void gray_show(bool enable)
|
||||||
{
|
{
|
||||||
|
#if (CONFIG_CPU == SH7034) && (CONFIG_LCD == LCD_SSD1815)
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
_gray_info.flags |= _GRAY_RUNNING;
|
_gray_info.flags |= _GRAY_RUNNING;
|
||||||
|
@ -265,6 +240,22 @@ void gray_show(bool enable)
|
||||||
_gray_info.flags &= ~_GRAY_RUNNING;
|
_gray_info.flags &= ~_GRAY_RUNNING;
|
||||||
_gray_rb->lcd_update(); /* restore whatever there was before */
|
_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 */
|
/* 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
|
do
|
||||||
{
|
{
|
||||||
#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
|
#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
|
||||||
unsigned mask;
|
|
||||||
unsigned long change;
|
|
||||||
unsigned long pat_stack[8];
|
unsigned long pat_stack[8];
|
||||||
unsigned long *pat_ptr;
|
unsigned long *pat_ptr;
|
||||||
unsigned char *end_addr;
|
unsigned change, ofs;
|
||||||
|
|
||||||
asm (
|
ofs = srcofs_row;
|
||||||
"mov.l @(%3,%1),r1 \n"
|
asm volatile (
|
||||||
"mov.l @(%3,%2),r2 \n"
|
"mov.l @(%[ofs],%[cbuf]),r1\n"
|
||||||
|
"mov.l @(%[ofs],%[bbuf]),r2\n"
|
||||||
"xor r1,r2 \n"
|
"xor r1,r2 \n"
|
||||||
"add #4,%3 \n"
|
"add #4,%[ofs] \n"
|
||||||
"mov.l @(%3,%1),r1 \n"
|
"mov.l @(%[ofs],%[cbuf]),r1\n"
|
||||||
"mov.l @(%3,%2),%0 \n"
|
"mov.l @(%[ofs],%[bbuf]),%[chg]\n"
|
||||||
"xor r1,%0 \n"
|
"xor r1,%[chg] \n"
|
||||||
"or r2,%0 \n"
|
"or r2,%[chg] \n"
|
||||||
: /* outputs */
|
: /* outputs */
|
||||||
/* %0 */ "=r"(change)
|
[ofs] "+z"(ofs),
|
||||||
|
[chg] "=r"(change)
|
||||||
: /* inputs */
|
: /* inputs */
|
||||||
/* %1 */ "r"(_gray_info.cur_buffer),
|
[cbuf]"r"(_gray_info.cur_buffer),
|
||||||
/* %2 */ "r"(_gray_info.back_buffer),
|
[bbuf]"r"(_gray_info.back_buffer)
|
||||||
/* %3 */ "z"(srcofs_row)
|
|
||||||
: /* clobbers */
|
: /* clobbers */
|
||||||
"r1", "r2"
|
"r1", "r2"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (change != 0)
|
if (change != 0)
|
||||||
{
|
{
|
||||||
|
unsigned char *cbuf, *bbuf, *addr, *end;
|
||||||
|
unsigned mask;
|
||||||
|
|
||||||
pat_ptr = &pat_stack[8];
|
pat_ptr = &pat_stack[8];
|
||||||
|
cbuf = _gray_info.cur_buffer;
|
||||||
|
bbuf = _gray_info.back_buffer;
|
||||||
|
|
||||||
/* precalculate the bit patterns with random shifts
|
/* precalculate the bit patterns with random shifts
|
||||||
* for all 8 pixels and put them on an extra "stack" */
|
* for all 8 pixels and put them on an extra "stack" */
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"add %5,%3 \n"
|
"add %[ofs],%[cbuf] \n"
|
||||||
"add %5,%4 \n"
|
"add %[ofs],%[bbuf] \n"
|
||||||
"mov #8,r3 \n" /* loop count in r3: 8 pixels */
|
"mov #8,r3 \n" /* loop count in r3: 8 pixels */
|
||||||
|
|
||||||
".ur_pre_loop: \n"
|
".ur_pre_loop: \n"
|
||||||
"mov.b @%3+,r0 \n" /* read current buffer */
|
"mov.b @%[cbuf]+,r0\n" /* read current buffer */
|
||||||
"mov.b @%4,r1 \n" /* read back buffer */
|
"mov.b @%[bbuf],r1 \n" /* read back buffer */
|
||||||
"mov #0,r2 \n" /* preset for skipped pixel */
|
"mov #0,r2 \n" /* preset for skipped pixel */
|
||||||
"mov.b r0,@%4 \n" /* update back buffer */
|
"mov.b r0,@%[bbuf] \n" /* update back buffer */
|
||||||
"add #1,%4 \n"
|
"add #1,%[bbuf] \n"
|
||||||
"cmp/eq r0,r1 \n" /* no change? */
|
"cmp/eq r0,r1 \n" /* no change? */
|
||||||
"bt .ur_skip \n" /* -> skip */
|
"bt .ur_skip \n" /* -> skip */
|
||||||
|
|
||||||
"shll2 r0 \n" /* pixel value -> pattern offset */
|
"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"
|
"mov #75,r0 \n"
|
||||||
"mulu r0,%0 \n" /* multiply by 75 */
|
"mulu r0,%[rnd] \n" /* multiply by 75 */
|
||||||
"sts macl,%0 \n"
|
"sts macl,%[rnd] \n"
|
||||||
"add #74,%0 \n" /* add another 74 */
|
"add #74,%[rnd] \n" /* add another 74 */
|
||||||
/* Since the lower bits are not very random: */
|
/* Since the lower bits are not very random: */
|
||||||
"swap.b %0,r1 \n" /* get bits 8..15 (need max. 5) */
|
"swap.b %[rnd],r1 \n" /* get bits 8..15 (need max. 5) */
|
||||||
"and %8,r1 \n" /* mask out unneeded bits */
|
"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"
|
"bf .ur_ntrim \n"
|
||||||
"sub %6,r1 \n" /* yes: random -= depth; */
|
"sub %[dpth],r1 \n" /* yes: random -= depth; */
|
||||||
".ur_ntrim: \n"
|
".ur_ntrim: \n"
|
||||||
|
|
||||||
"mov.l .ashlsi3,r0 \n" /** rotate pattern **/
|
"mov.l .ashlsi3,r0 \n" /** rotate pattern **/
|
||||||
"jsr @r0 \n" /* r4 -> r0, shift left by r5 */
|
"jsr @r0 \n" /* r4 -> r0, shift left by r5 */
|
||||||
"mov r1,r5 \n"
|
"mov r1,r5 \n"
|
||||||
|
|
||||||
"mov %6,r5 \n"
|
"mov %[dpth],r5 \n"
|
||||||
"sub r1,r5 \n" /* r5 = depth - r1 */
|
"sub r1,r5 \n" /* r5 = depth - r1 */
|
||||||
"mov.l .lshrsi3,r1 \n"
|
"mov.l .lshrsi3,r1 \n"
|
||||||
"jsr @r1 \n" /* r4 -> r0, shift right by r5 */
|
"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) */
|
"clrt \n" /* mask bit = 0 (replace) */
|
||||||
|
|
||||||
".ur_skip: \n" /* T == 1 if skipped */
|
".ur_skip: \n" /* T == 1 if skipped */
|
||||||
"rotcr %2 \n" /* get mask bit */
|
"rotcr %[mask] \n" /* get mask bit */
|
||||||
"mov.l r2,@-%1 \n" /* push on pattern stack */
|
"mov.l r2,@-%[patp]\n" /* push on pattern stack */
|
||||||
|
|
||||||
"add #-1,r3 \n" /* decrease loop count */
|
"add #-1,r3 \n" /* decrease loop count */
|
||||||
"cmp/pl r3 \n" /* loop count > 0? */
|
"cmp/pl r3 \n" /* loop count > 0? */
|
||||||
"bt .ur_pre_loop\n" /* yes: loop */
|
"bt .ur_pre_loop\n" /* yes: loop */
|
||||||
"shlr8 %2 \n"
|
"shlr8 %[mask] \n"
|
||||||
"shlr16 %2 \n"
|
"shlr16 %[mask] \n"
|
||||||
: /* outputs */
|
: /* outputs */
|
||||||
/* %0, in & out */ "+r"(_gray_random_buffer),
|
[cbuf]"+r"(cbuf),
|
||||||
/* %1, in & out */ "+r"(pat_ptr),
|
[bbuf]"+r"(bbuf),
|
||||||
/* %2 */ "=&r"(mask)
|
[rnd] "+r"(_gray_random_buffer),
|
||||||
|
[patp]"+r"(pat_ptr),
|
||||||
|
[mask]"=&r"(mask)
|
||||||
: /* inputs */
|
: /* inputs */
|
||||||
/* %3 */ "r"(_gray_info.cur_buffer),
|
[ofs] "[mask]"(srcofs_row),
|
||||||
/* %4 */ "r"(_gray_info.back_buffer),
|
[dpth]"r"(_gray_info.depth),
|
||||||
/* %5 */ "2"(srcofs_row),
|
[bpat]"r"(_gray_info.bitpattern),
|
||||||
/* %6 */ "r"(_gray_info.depth),
|
[rmsk]"r"(_gray_info.randmask)
|
||||||
/* %7 */ "r"(_gray_info.bitpattern),
|
|
||||||
/* %8 */ "r"(_gray_info.randmask)
|
|
||||||
: /* clobbers */
|
: /* clobbers */
|
||||||
"r0", "r1", "r2", "r3", "r4", "r5", "macl", "pr"
|
"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
|
/* 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 @%[patp]+,r1\n" /* pop all 8 patterns */
|
||||||
"mov.l @%3+,r2 \n"
|
"mov.l @%[patp]+,r2\n"
|
||||||
"mov.l @%3+,r3 \n"
|
"mov.l @%[patp]+,r3\n"
|
||||||
"mov.l @%3+,r6 \n"
|
"mov.l @%[patp]+,r6\n"
|
||||||
"mov.l @%3+,r7 \n"
|
"mov.l @%[patp]+,r7\n"
|
||||||
"mov.l @%3+,r8 \n"
|
"mov.l @%[patp]+,r8\n"
|
||||||
"mov.l @%3+,r9 \n"
|
"mov.l @%[patp]+,r9\n"
|
||||||
"mov.l @%3+,r10 \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 */
|
"bt .ur_sloop \n" /* yes: jump to short loop */
|
||||||
|
|
||||||
".ur_floop: \n" /** full loop (there are bits to keep)**/
|
".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"
|
"shlr r9 \n"
|
||||||
"rotcl r0 \n"
|
"rotcl r0 \n"
|
||||||
"shlr r10 \n"
|
"shlr r10 \n"
|
||||||
"mov.b @%0,%3 \n" /* read old value */
|
"mov.b @%[addr],%[patp]\n" /* read old value */
|
||||||
"rotcl r0 \n"
|
"rotcl r0 \n"
|
||||||
"and %4,%3 \n" /* mask out unneeded bits */
|
"and %[mask],%[patp] \n" /* mask out unneeded bits */
|
||||||
"or r0,%3 \n" /* set new bits */
|
"or %[patp],r0 \n" /* set new bits */
|
||||||
"mov.b %3,@%0 \n" /* store value to bitplane */
|
"mov.b r0,@%[addr] \n" /* store value to bitplane */
|
||||||
"add %2,%0 \n" /* advance to next bitplane */
|
"add %[psiz],%[addr] \n" /* advance to next bitplane */
|
||||||
"cmp/hi %0,%1 \n" /* last bitplane done? */
|
"cmp/hi %[addr],%[end] \n" /* last bitplane done? */
|
||||||
"bt .ur_floop \n" /* no: loop */
|
"bt .ur_floop \n" /* no: loop */
|
||||||
|
|
||||||
"bra .ur_end \n"
|
"bra .ur_end \n"
|
||||||
|
@ -459,23 +455,184 @@ void gray_update_rect(int x, int y, int width, int height)
|
||||||
"rotcl r0 \n"
|
"rotcl r0 \n"
|
||||||
"shlr r10 \n"
|
"shlr r10 \n"
|
||||||
"rotcl r0 \n"
|
"rotcl r0 \n"
|
||||||
"mov.b r0,@%0 \n" /* store byte to bitplane */
|
"mov.b r0,@%[addr] \n" /* store byte to bitplane */
|
||||||
"add %2,%0 \n" /* advance to next bitplane */
|
"add %[psiz],%[addr] \n" /* advance to next bitplane */
|
||||||
"cmp/hi %0,%1 \n" /* last bitplane done? */
|
"cmp/hi %[addr],%[end] \n" /* last bitplane done? */
|
||||||
"bt .ur_sloop \n" /* no: loop */
|
"bt .ur_sloop \n" /* no: loop */
|
||||||
|
|
||||||
".ur_end: \n"
|
".ur_end: \n"
|
||||||
: /* outputs */
|
: /* outputs */
|
||||||
|
[patp]"+r"(pat_ptr),
|
||||||
|
[addr]"+r"(addr),
|
||||||
|
[mask]"+r"(mask)
|
||||||
: /* inputs */
|
: /* inputs */
|
||||||
/* %0 */ "r"(dst_row),
|
[end] "r"(end),
|
||||||
/* %1 */ "r"(end_addr),
|
[psiz]"r"(_gray_info.plane_size)
|
||||||
/* %2 */ "r"(_gray_info.plane_size),
|
|
||||||
/* %3 */ "r"(pat_ptr),
|
|
||||||
/* %4 */ "r"(mask)
|
|
||||||
: /* clobbers */
|
: /* clobbers */
|
||||||
"r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10"
|
"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
|
#endif
|
||||||
srcofs_row += _gray_info.height;
|
srcofs_row += _gray_info.height;
|
||||||
dst_row++;
|
dst_row++;
|
||||||
|
@ -517,7 +674,7 @@ void gray_deferred_lcd_update(void)
|
||||||
|
|
||||||
/*** Screenshot ***/
|
/*** Screenshot ***/
|
||||||
|
|
||||||
#define BMP_NUMCOLORS (_MAX_DEPTH * _LEVEL_FAC + 1)
|
#define BMP_NUMCOLORS 33
|
||||||
#define BMP_BPP 8
|
#define BMP_BPP 8
|
||||||
#define BMP_LINESIZE ((LCD_WIDTH + 3) & ~3)
|
#define BMP_LINESIZE ((LCD_WIDTH + 3) & ~3)
|
||||||
#define BMP_HEADERSIZE (54 + 4 * BMP_NUMCOLORS)
|
#define BMP_HEADERSIZE (54 + 4 * BMP_NUMCOLORS)
|
||||||
|
@ -564,9 +721,12 @@ static unsigned char linebuf[BMP_LINESIZE];
|
||||||
void gray_screendump(void)
|
void gray_screendump(void)
|
||||||
{
|
{
|
||||||
int fh, i, bright;
|
int fh, i, bright;
|
||||||
int x, y, by, mask;
|
int y;
|
||||||
|
#if LCD_DEPTH == 1
|
||||||
|
int x, by, mask;
|
||||||
int gx, gby;
|
int gx, gby;
|
||||||
unsigned char *lcdptr, *grayptr, *grayptr2;
|
unsigned char *lcdptr, *grayptr, *grayptr2;
|
||||||
|
#endif
|
||||||
char filename[MAX_PATH];
|
char filename[MAX_PATH];
|
||||||
|
|
||||||
#ifdef HAVE_RTC
|
#ifdef HAVE_RTC
|
||||||
|
@ -617,24 +777,24 @@ void gray_screendump(void)
|
||||||
|
|
||||||
_gray_rb->write(fh, bmpheader, sizeof(bmpheader)); /* write header */
|
_gray_rb->write(fh, bmpheader, sizeof(bmpheader)); /* write header */
|
||||||
|
|
||||||
/* build clut, always 33 entries */
|
/* build clut */
|
||||||
linebuf[3] = 0;
|
linebuf[3] = 0;
|
||||||
|
|
||||||
for (i = 0; i < BMP_NUMCOLORS; i++)
|
for (i = 0; i < BMP_NUMCOLORS; i++)
|
||||||
{
|
{
|
||||||
bright = MIN(i, _LEVEL_FAC * _gray_info.depth);
|
bright = MIN(i, _gray_info.depth);
|
||||||
linebuf[0] = MULU16(BMP_BLUE, bright) / (_LEVEL_FAC * _gray_info.depth);
|
linebuf[0] = MULU16(BMP_BLUE, bright) / _gray_info.depth;
|
||||||
linebuf[1] = MULU16(BMP_GREEN, bright) / (_LEVEL_FAC * _gray_info.depth);
|
linebuf[1] = MULU16(BMP_GREEN, bright) / _gray_info.depth;
|
||||||
linebuf[2] = MULU16(BMP_RED, bright) / (_LEVEL_FAC * _gray_info.depth);
|
linebuf[2] = MULU16(BMP_RED, bright) / _gray_info.depth;
|
||||||
_gray_rb->write(fh, linebuf, 4);
|
_gray_rb->write(fh, linebuf, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 8-bit BMP image goes bottom -> top */
|
/* 8-bit BMP image goes bottom -> top */
|
||||||
for (y = LCD_HEIGHT - 1; y >= 0; y--)
|
for (y = LCD_HEIGHT - 1; y >= 0; y--)
|
||||||
{
|
{
|
||||||
#if LCD_DEPTH == 1
|
|
||||||
_gray_rb->memset(linebuf, BMP_NUMCOLORS-1, LCD_WIDTH);
|
_gray_rb->memset(linebuf, BMP_NUMCOLORS-1, LCD_WIDTH);
|
||||||
|
|
||||||
|
#if LCD_DEPTH == 1
|
||||||
mask = 1 << (y & 7);
|
mask = 1 << (y & 7);
|
||||||
by = y >> 3;
|
by = y >> 3;
|
||||||
lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by);
|
lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by);
|
||||||
|
@ -675,6 +835,8 @@ void gray_screendump(void)
|
||||||
if (*lcdptr++ & mask)
|
if (*lcdptr++ & mask)
|
||||||
linebuf[x] = 0;
|
linebuf[x] = 0;
|
||||||
}
|
}
|
||||||
|
#elif LCD_DEPTH == 2
|
||||||
|
/* TODO */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_gray_rb->write(fh, linebuf, sizeof(linebuf));
|
_gray_rb->write(fh, linebuf, sizeof(linebuf));
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* Greyscale framework
|
* Greyscale framework
|
||||||
* Drawing functions for buffered mode
|
* Drawing functions
|
||||||
*
|
*
|
||||||
* This is a generic framework to use grayscale display within Rockbox
|
* This is a generic framework to use grayscale display within Rockbox
|
||||||
* plugins. It obviously does not work for the player.
|
* 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)
|
static void flippixel(unsigned char *address)
|
||||||
{
|
{
|
||||||
*address = _LEVEL_FAC * _gray_info.depth - *address;
|
*address = _gray_info.depth - *address;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nopixel(unsigned char *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;
|
dst_end = dst_col + height;
|
||||||
do
|
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 */
|
*dst_col++ = (data + (data >> 8)) >> 8; /* approx. data / 255 */
|
||||||
src_col += stride;
|
src_col += stride;
|
||||||
}
|
}
|
||||||
|
@ -586,22 +586,26 @@ static void _writearray(unsigned char *address, const unsigned char *src,
|
||||||
#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
|
#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
|
||||||
unsigned long pat_stack[8];
|
unsigned long pat_stack[8];
|
||||||
unsigned long *pat_ptr = &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
|
/* precalculate the bit patterns with random shifts
|
||||||
for all 8 pixels and put them on an extra "stack" */
|
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 #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 **/
|
".wa_loop: \n" /** load pattern for pixel **/
|
||||||
"mov #0,r0 \n" /* pattern for skipped pixel must be 0 */
|
"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 */
|
"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 */
|
"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; */
|
"sts macl,r1 \n" /* r1 = macl; */
|
||||||
"add #127,r1 \n" /* byte += 127; */
|
"add #127,r1 \n" /* byte += 127; */
|
||||||
"mov r1,r0 \n"
|
"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; */
|
"add r1,r0 \n" /* byte += byte >> 8; */
|
||||||
"shlr8 r0 \n" /* byte >>= 8; */
|
"shlr8 r0 \n" /* byte >>= 8; */
|
||||||
"shll2 r0 \n"
|
"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"
|
"mov #75,r0 \n"
|
||||||
"mulu r0,%0 \n" /* multiply by 75 */
|
"mulu r0,%[rnd] \n" /* multiply by 75 */
|
||||||
"sts macl,%0 \n"
|
"sts macl,%[rnd] \n"
|
||||||
"add #74,%0 \n" /* add another 74 */
|
"add #74,%[rnd] \n" /* add another 74 */
|
||||||
/* Since the lower bits are not very random: */
|
/* Since the lower bits are not very random: */
|
||||||
"swap.b %0,r1 \n" /* get bits 8..15 (need max. 5) */
|
"swap.b %[rnd],r1 \n" /* get bits 8..15 (need max. 5) */
|
||||||
"and %6,r1 \n" /* mask out unneeded bits */
|
"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"
|
"bf .wa_ntrim \n"
|
||||||
"sub %4,r1 \n" /* yes: random -= depth; */
|
"sub %[dpth],r1 \n" /* yes: random -= depth; */
|
||||||
".wa_ntrim: \n"
|
".wa_ntrim: \n"
|
||||||
|
|
||||||
"mov.l .ashlsi3,r0 \n" /** rotate pattern **/
|
"mov.l .ashlsi3,r0 \n" /** rotate pattern **/
|
||||||
"jsr @r0 \n" /* r4 -> r0, shift left by r5 */
|
"jsr @r0 \n" /* r4 -> r0, shift left by r5 */
|
||||||
"mov r1,r5 \n"
|
"mov r1,r5 \n"
|
||||||
|
|
||||||
"mov %4,r5 \n"
|
"mov %[dpth],r5 \n"
|
||||||
"sub r1,r5 \n" /* r5 = depth - r1 */
|
"sub r1,r5 \n" /* r5 = depth - r1 */
|
||||||
"mov.l .lshrsi3,r1 \n"
|
"mov.l .lshrsi3,r1 \n"
|
||||||
"jsr @r1 \n" /* r4 -> r0, shift right by r5 */
|
"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 */
|
"or r1,r0 \n" /* rotated_pattern = r0 | r1 */
|
||||||
|
|
||||||
".wa_skip: \n"
|
".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 */
|
"add #-1,r3 \n" /* decrease loop count */
|
||||||
"cmp/pl r3 \n" /* loop count > 0? */
|
"cmp/pl r3 \n" /* loop count > 0? */
|
||||||
"bt .wa_loop \n" /* yes: loop */
|
"bt .wa_loop \n" /* yes: loop */
|
||||||
: /* outputs */
|
: /* outputs */
|
||||||
/* %0, in & out */ "+r"(_gray_random_buffer),
|
[src] "+r"(_src),
|
||||||
/* %1, in & out */ "+r"(pat_ptr)
|
[rnd] "+r"(_gray_random_buffer),
|
||||||
|
[patp]"+r"(pat_ptr),
|
||||||
|
[mask]"+r"(_mask)
|
||||||
: /* inputs */
|
: /* inputs */
|
||||||
/* %2 */ "r"(src),
|
[stri]"r"(stride),
|
||||||
/* %3 */ "r"(stride),
|
[dpth]"r"(_gray_info.depth),
|
||||||
/* %4 */ "r"(_gray_info.depth),
|
[bpat]"r"(_gray_info.bitpattern),
|
||||||
/* %5 */ "r"(_gray_info.bitpattern),
|
[rmsk]"r"(_gray_info.randmask)
|
||||||
/* %6 */ "r"(_gray_info.randmask),
|
|
||||||
/* %7 */ "r"(mask)
|
|
||||||
: /* clobbers */
|
: /* 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
|
/* 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 @%[patp]+,r1\n" /* pop all 8 patterns */
|
||||||
"mov.l @%3+,r2 \n"
|
"mov.l @%[patp]+,r2\n"
|
||||||
"mov.l @%3+,r3 \n"
|
"mov.l @%[patp]+,r3\n"
|
||||||
"mov.l @%3+,r8 \n"
|
"mov.l @%[patp]+,r6\n"
|
||||||
"mov.l @%3+,r9 \n"
|
"mov.l @%[patp]+,r7\n"
|
||||||
"mov.l @%3+,r10 \n"
|
"mov.l @%[patp]+,r8\n"
|
||||||
"mov.l @%3+,r11 \n"
|
"mov.l @%[patp]+,r9\n"
|
||||||
"mov.l @%3+,r12 \n"
|
"mov.l @%[patp]+,r10 \n"
|
||||||
|
|
||||||
"not %4,%4 \n" /* "set" mask -> "keep" mask */
|
"not %[mask],%[mask] \n" /* "set" mask -> "keep" mask */
|
||||||
"extu.b %4,%4 \n" /* mask out high bits */
|
"extu.b %[mask],%[mask] \n" /* mask out high bits */
|
||||||
"tst %4,%4 \n" /* nothing to keep? */
|
"tst %[mask],%[mask] \n" /* nothing to keep? */
|
||||||
"bt .wa_sloop \n" /* yes: jump to short loop */
|
"bt .wa_sloop \n" /* yes: jump to short loop */
|
||||||
|
|
||||||
".wa_floop: \n" /** full loop (there are bits to keep)**/
|
".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"
|
"rotcl r0 \n"
|
||||||
"shlr r3 \n"
|
"shlr r3 \n"
|
||||||
"rotcl r0 \n"
|
"rotcl r0 \n"
|
||||||
|
"shlr r6 \n"
|
||||||
|
"rotcl r0 \n"
|
||||||
|
"shlr r7 \n"
|
||||||
|
"rotcl r0 \n"
|
||||||
"shlr r8 \n"
|
"shlr r8 \n"
|
||||||
"rotcl r0 \n"
|
"rotcl r0 \n"
|
||||||
"shlr r9 \n"
|
"shlr r9 \n"
|
||||||
"rotcl r0 \n"
|
"rotcl r0 \n"
|
||||||
"shlr r10 \n"
|
"shlr r10 \n"
|
||||||
|
"mov.b @%[addr],%[patp]\n" /* read old value */
|
||||||
"rotcl r0 \n"
|
"rotcl r0 \n"
|
||||||
"shlr r11 \n"
|
"and %[mask],%[patp] \n" /* mask out unneeded bits */
|
||||||
"rotcl r0 \n"
|
"or %[patp],r0 \n" /* set new bits */
|
||||||
"shlr r12 \n"
|
"mov.b r0,@%[addr] \n" /* store value to bitplane */
|
||||||
"mov.b @%0,%3 \n" /* read old value */
|
"add %[psiz],%[addr] \n" /* advance to next bitplane */
|
||||||
"rotcl r0 \n"
|
"cmp/hi %[addr],%[end] \n" /* last bitplane done? */
|
||||||
"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? */
|
|
||||||
"bt .wa_floop \n" /* no: loop */
|
"bt .wa_floop \n" /* no: loop */
|
||||||
|
|
||||||
"bra .wa_end \n"
|
"bra .wa_end \n"
|
||||||
|
@ -711,31 +717,174 @@ static void _writearray(unsigned char *address, const unsigned char *src,
|
||||||
"rotcl r0 \n"
|
"rotcl r0 \n"
|
||||||
"shlr r3 \n"
|
"shlr r3 \n"
|
||||||
"rotcl r0 \n"
|
"rotcl r0 \n"
|
||||||
|
"shlr r6 \n"
|
||||||
|
"rotcl r0 \n"
|
||||||
|
"shlr r7 \n"
|
||||||
|
"rotcl r0 \n"
|
||||||
"shlr r8 \n"
|
"shlr r8 \n"
|
||||||
"rotcl r0 \n"
|
"rotcl r0 \n"
|
||||||
"shlr r9 \n"
|
"shlr r9 \n"
|
||||||
"rotcl r0 \n"
|
"rotcl r0 \n"
|
||||||
"shlr r10 \n"
|
"shlr r10 \n"
|
||||||
"rotcl r0 \n"
|
"rotcl r0 \n"
|
||||||
"shlr r11 \n"
|
"mov.b r0,@%[addr] \n" /* store byte to bitplane */
|
||||||
"rotcl r0 \n"
|
"add %[psiz],%[addr] \n" /* advance to next bitplane */
|
||||||
"shlr r12 \n"
|
"cmp/hi %[addr],%[end] \n" /* last bitplane done? */
|
||||||
"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? */
|
|
||||||
"bt .wa_sloop \n" /* no: loop */
|
"bt .wa_sloop \n" /* no: loop */
|
||||||
|
|
||||||
".wa_end: \n"
|
".wa_end: \n"
|
||||||
: /* outputs */
|
: /* outputs */
|
||||||
|
[patp]"+r"(pat_ptr),
|
||||||
|
[addr]"+r"(addr),
|
||||||
|
[mask]"+r"(_mask)
|
||||||
: /* inputs */
|
: /* inputs */
|
||||||
/* %0 */ "r"(address),
|
[end] "r"(end),
|
||||||
/* %1 */ "r"(end_addr),
|
[psiz]"r"(_gray_info.plane_size)
|
||||||
/* %2 */ "r"(_gray_info.plane_size),
|
|
||||||
/* %3 */ "r"(pat_ptr),
|
|
||||||
/* %4 */ "r"(mask)
|
|
||||||
: /* clobbers */
|
: /* 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
|
#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);
|
+ MULU16(_gray_info.width, y >> _PBLOCK_EXP);
|
||||||
ny = height - 1 + shift;
|
ny = height - 1 + shift;
|
||||||
|
|
||||||
mask = 0xFFu << shift; /* ATTN LCD_DEPTH == 2 */
|
mask = 0xFFu << (LCD_DEPTH * shift);
|
||||||
mask_bottom = 0xFFu >> (~ny & (_PBLOCK-1));
|
mask_bottom = 0xFFu >> (LCD_DEPTH * (~ny & (_PBLOCK-1)));
|
||||||
|
|
||||||
for (; ny >= _PBLOCK; ny -= _PBLOCK)
|
for (; ny >= _PBLOCK; ny -= _PBLOCK)
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,7 +55,7 @@ int gray_get_drawmode(void)
|
||||||
/* Set the foreground shade for subsequent drawing operations */
|
/* Set the foreground shade for subsequent drawing operations */
|
||||||
void gray_set_foreground(int brightness)
|
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 */
|
_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 */
|
/* Return the current foreground shade */
|
||||||
int gray_get_foreground(void)
|
int gray_get_foreground(void)
|
||||||
{
|
{
|
||||||
return (_gray_info.fg_brightness * 255 + ((_LEVEL_FAC * _gray_info.depth) >> 1))
|
return (_gray_info.fg_brightness * 255 + (_gray_info.depth >> 1))
|
||||||
/ (_LEVEL_FAC * _gray_info.depth);
|
/ _gray_info.depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the background shade for subsequent drawing operations */
|
/* Set the background shade for subsequent drawing operations */
|
||||||
void gray_set_background(int brightness)
|
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 */
|
_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 */
|
/* Return the current background shade */
|
||||||
int gray_get_background(void)
|
int gray_get_background(void)
|
||||||
{
|
{
|
||||||
return (_gray_info.bg_brightness * 255 + ((_LEVEL_FAC * _gray_info.depth) >> 1))
|
return (_gray_info.bg_brightness * 255 + (_gray_info.depth >> 1))
|
||||||
/ (_LEVEL_FAC * _gray_info.depth);
|
/ _gray_info.depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set draw mode, foreground and background shades at once */
|
/* Set draw mode, foreground and background shades at once */
|
||||||
|
|
|
@ -260,9 +260,9 @@ void gray_ub_scroll_up(int count)
|
||||||
asm (
|
asm (
|
||||||
"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,%5),%5 \n" /* shift amount from table */
|
"mov.b @(r0,%[cnt]),%[cnt] \n" /* shift amount from table */
|
||||||
"bra .su_cloop \n" /* skip table */
|
"bra .su_cloop \n" /* skip table */
|
||||||
"add r0,%5 \n"
|
"add r0,%[cnt] \n"
|
||||||
|
|
||||||
".align 2 \n"
|
".align 2 \n"
|
||||||
".su_shifttbl: \n" /* shift jump offset table */
|
".su_shifttbl: \n" /* shift jump offset table */
|
||||||
|
@ -276,7 +276,7 @@ void gray_ub_scroll_up(int count)
|
||||||
".byte .su_shift7 - .su_shifttbl \n"
|
".byte .su_shift7 - .su_shifttbl \n"
|
||||||
|
|
||||||
".su_cloop: \n" /* repeat for every column */
|
".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 */
|
"mov #0,r3 \n" /* current_plane = 0 */
|
||||||
|
|
||||||
".su_oloop: \n" /* repeat for every bitplane */
|
".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 */
|
"mov #0,r1 \n" /* fill with zero */
|
||||||
|
|
||||||
".su_iloop: \n" /* repeat for all rows */
|
".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 */
|
"mov.b @r4,r0 \n" /* get data byte */
|
||||||
"shll8 r1 \n" /* old data to 2nd byte */
|
"shll8 r1 \n" /* old data to 2nd byte */
|
||||||
"extu.b r0,r0 \n" /* extend unsigned */
|
"extu.b r0,r0 \n" /* extend unsigned */
|
||||||
"or r1,r0 \n" /* combine old data */
|
"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 */
|
"extu.b r0,r1 \n" /* store data for next round */
|
||||||
|
|
||||||
".su_shift6: \n" /* shift right by 0..7 bits */
|
".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 */
|
"mov.b r0,@r4 \n" /* store data */
|
||||||
"add #1,r5 \n" /* current_row++ */
|
"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"
|
"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++ */
|
"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"
|
"bt .su_oloop \n"
|
||||||
|
|
||||||
"add #1,%1 \n" /* start_address++ */
|
"add #1,%[addr] \n" /* start_address++ */
|
||||||
"add #1,r6 \n" /* x++ */
|
"add #1,r6 \n" /* x++ */
|
||||||
"cmp/hi r6,%2 \n" /* x < width ? */
|
"cmp/hi r6,%[wide] \n" /* x < width ? */
|
||||||
"bt .su_cloop \n"
|
"bt .su_cloop \n"
|
||||||
: /* outputs */
|
: /* outputs */
|
||||||
: /* inputs */
|
: /* inputs */
|
||||||
/* %0 */ "r"(_gray_info.depth),
|
[dpth]"r"(_gray_info.depth),
|
||||||
/* %1 */ "r"(_gray_info.plane_data + _gray_info.plane_size - blockshift),
|
[addr]"r"(_gray_info.plane_data + _gray_info.plane_size - blockshift),
|
||||||
/* %2 */ "r"(_gray_info.width),
|
[wide]"r"(_gray_info.width),
|
||||||
/* %3 */ "r"(_gray_info.bheight - shift),
|
[rows]"r"(_gray_info.bheight - shift),
|
||||||
/* %4 */ "r"(_gray_info.plane_size),
|
[psiz]"r"(_gray_info.plane_size),
|
||||||
/* %5 */ "r"(count)
|
[cnt] "r"(count)
|
||||||
: /* clobbers */
|
: /* clobbers */
|
||||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6"
|
"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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -396,9 +444,9 @@ void gray_ub_scroll_down(int count)
|
||||||
asm (
|
asm (
|
||||||
"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,%5),%5 \n" /* shift amount from table */
|
"mov.b @(r0,%[cnt]),%[cnt] \n" /* shift amount from table */
|
||||||
"bra .sd_cloop \n" /* skip table */
|
"bra .sd_cloop \n" /* skip table */
|
||||||
"add r0,%5 \n"
|
"add r0,%[cnt] \n"
|
||||||
|
|
||||||
".align 2 \n"
|
".align 2 \n"
|
||||||
".sd_shifttbl: \n" /* shift jump offset table */
|
".sd_shifttbl: \n" /* shift jump offset table */
|
||||||
|
@ -412,7 +460,7 @@ void gray_ub_scroll_down(int count)
|
||||||
".byte .sd_shift7 - .sd_shifttbl \n"
|
".byte .sd_shift7 - .sd_shifttbl \n"
|
||||||
|
|
||||||
".sd_cloop: \n" /* repeat for every column */
|
".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 */
|
"mov #0,r3 \n" /* current_plane = 0 */
|
||||||
|
|
||||||
".sd_oloop: \n" /* repeat for every bitplane */
|
".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 */
|
".sd_iloop: \n" /* repeat for all rows */
|
||||||
"shlr8 r1 \n" /* shift right to get residue */
|
"shlr8 r1 \n" /* shift right to get residue */
|
||||||
"mov.b @r4,r0 \n" /* get data byte */
|
"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 */
|
"extu.b r0,r0 \n" /* extend unsigned */
|
||||||
|
|
||||||
".sd_shift6: \n" /* shift left by 0..7 bits */
|
".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 */
|
"or r0,r1 \n" /* combine with last residue */
|
||||||
"mov.b r1,@r4 \n" /* store data */
|
"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++ */
|
"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"
|
"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++ */
|
"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"
|
"bt .sd_oloop \n"
|
||||||
|
|
||||||
"add #1,%1 \n" /* start_address++ */
|
"add #1,%[addr] \n" /* start_address++ */
|
||||||
"add #1,r6 \n" /* x++ */
|
"add #1,r6 \n" /* x++ */
|
||||||
"cmp/hi r6,%2 \n" /* x < width ? */
|
"cmp/hi r6,%[wide] \n" /* x < width ? */
|
||||||
"bt .sd_cloop \n"
|
"bt .sd_cloop \n"
|
||||||
: /* outputs */
|
: /* outputs */
|
||||||
: /* inputs */
|
: /* inputs */
|
||||||
/* %0 */ "r"(_gray_info.depth),
|
[dpth]"r"(_gray_info.depth),
|
||||||
/* %1 */ "r"(_gray_info.plane_data + blockshift),
|
[addr]"r"(_gray_info.plane_data + blockshift),
|
||||||
/* %2 */ "r"(_gray_info.width),
|
[wide]"r"(_gray_info.width),
|
||||||
/* %3 */ "r"(_gray_info.bheight - shift),
|
[rows]"r"(_gray_info.bheight - shift),
|
||||||
/* %4 */ "r"(_gray_info.plane_size),
|
[psiz]"r"(_gray_info.plane_size),
|
||||||
/* %5 */ "r"(count)
|
[cnt] "r"(count)
|
||||||
: /* clobbers */
|
: /* clobbers */
|
||||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6"
|
"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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue