1
0
Fork 0
forked from len0rd/rockbox

Core: A graphics framework can now register a hook function to extend the core screendump routine. * Grayscale library: (1) Changed the screendump routine into a hook, and implemented it for H1x0. (2) The planar pixel setting routines now use one register less. Fixes build problem with developer builds (frame pointers enabled) on coldfire.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7574 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2005-10-01 10:20:55 +00:00
parent f0fe3c9477
commit 05042affc7
7 changed files with 205 additions and 167 deletions

View file

@ -274,6 +274,8 @@ static const unsigned char bmpheader[] =
#endif #endif
}; };
static void (*screen_dump_hook)(int fh) = NULL;
void screen_dump(void) void screen_dump(void)
{ {
int fh; int fh;
@ -298,56 +300,70 @@ void screen_dump(void)
if (fh < 0) if (fh < 0)
return; return;
write(fh, bmpheader, sizeof(bmpheader)); if (screen_dump_hook)
{
screen_dump_hook(fh);
}
else
{
write(fh, bmpheader, sizeof(bmpheader));
/* BMP image goes bottom up */ /* BMP image goes bottom up */
#if LCD_DEPTH == 1 #if LCD_DEPTH == 1
for (by = LCD_HEIGHT/8 - 1; by >= 0; by--) for (by = LCD_HEIGHT/8 - 1; by >= 0; by--)
{
memset(&line_block[0][0], 0, sizeof(line_block));
for (bx = 0; bx < LCD_WIDTH/8; bx++)
{ {
dst_mask = 0x01; memset(&line_block[0][0], 0, sizeof(line_block));
for (ix = 7; ix >= 0; ix--)
for (bx = 0; bx < LCD_WIDTH/8; bx++)
{ {
src_byte = lcd_framebuffer[by][8*bx+ix]; dst_mask = 0x01;
src_mask = 0x01; for (ix = 7; ix >= 0; ix--)
for (iy = 7; iy >= 0; iy--)
{ {
if (src_byte & src_mask) src_byte = lcd_framebuffer[by][8*bx+ix];
line_block[iy][bx] |= dst_mask; src_mask = 0x01;
src_mask <<= 1; for (iy = 7; iy >= 0; iy--)
{
if (src_byte & src_mask)
line_block[iy][bx] |= dst_mask;
src_mask <<= 1;
}
dst_mask <<= 1;
} }
dst_mask <<= 1;
} }
write(fh, &line_block[0][0], sizeof(line_block));
} }
write(fh, &line_block[0][0], sizeof(line_block));
}
#elif LCD_DEPTH == 2 #elif LCD_DEPTH == 2
for (by = LCD_HEIGHT/4 - 1; by >= 0; by--) for (by = LCD_HEIGHT/4 - 1; by >= 0; by--)
{
memset(&line_block[0][0], 0, sizeof(line_block));
for (bx = 0; bx < LCD_WIDTH/2; bx++)
{ {
src_byte = lcd_framebuffer[by][2*bx]; memset(&line_block[0][0], 0, sizeof(line_block));
src_byte2 = lcd_framebuffer[by][2*bx+1];
for (iy = 3; iy >= 0; iy--)
{
line_block[iy][bx] = ((src_byte & 3) << 4) | (src_byte2 & 3);
src_byte >>= 2;
src_byte2 >>= 2;
}
}
write(fh, &line_block[0][0], sizeof(line_block)); for (bx = 0; bx < LCD_WIDTH/2; bx++)
{
src_byte = lcd_framebuffer[by][2*bx];
src_byte2 = lcd_framebuffer[by][2*bx+1];
for (iy = 3; iy >= 0; iy--)
{
line_block[iy][bx] = ((src_byte & 3) << 4) | (src_byte2 & 3);
src_byte >>= 2;
src_byte2 >>= 2;
}
}
write(fh, &line_block[0][0], sizeof(line_block));
}
#endif /* LCD_DEPTH */
} }
#endif
close(fh); close(fh);
} }
#endif
void screen_dump_set_hook(void (*hook)(int fh))
{
screen_dump_hook = hook;
}
#endif /* HAVE_LCD_BITMAP */
/* parse a line from a configuration file. the line format is: /* parse a line from a configuration file. the line format is:

View file

@ -46,6 +46,7 @@ int read_line(int fd, char* buffer, int buffer_size);
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
/* Save a .BMP file containing the current screen contents. */ /* Save a .BMP file containing the current screen contents. */
void screen_dump(void); void screen_dump(void);
void screen_dump_set_hook(void (*hook)(int fh));
#endif #endif
bool settings_parseline(char* line, char** name, char** value); bool settings_parseline(char* line, char** name, char** value);

View file

@ -355,6 +355,8 @@ static const struct plugin_api rockbox_api = {
menu_draw, menu_draw,
menu_insert, menu_insert,
menu_set_cursor, menu_set_cursor,
screen_dump_set_hook,
}; };
int plugin_load(const char* plugin, void* parameter) int plugin_load(const char* plugin, void* parameter)

View file

@ -90,7 +90,7 @@
#endif #endif
/* increase this every time the api struct changes */ /* increase this every time the api struct changes */
#define PLUGIN_API_VERSION 51 #define PLUGIN_API_VERSION 52
/* update this to latest version if a change to the api struct breaks /* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any backwards compatibility (and please take the opportunity to sort in any
@ -443,6 +443,8 @@ struct plugin_api {
void (*menu_draw)(int menu); void (*menu_draw)(int menu);
void (*menu_insert)(int menu, int position, char *desc, bool (*function) (void)); void (*menu_insert)(int menu, int position, char *desc, bool (*function) (void));
void (*menu_set_cursor)(int menu, int position); void (*menu_set_cursor)(int menu, int position);
void (*screen_dump_set_hook)(void (*hook)(int fh));
}; };
int plugin_load(const char* plugin, void* parameter); int plugin_load(const char* plugin, void* parameter);

View file

@ -42,7 +42,6 @@ void gray_release(void);
/* Special functions */ /* Special functions */
void gray_show(bool enable); void gray_show(bool enable);
void gray_deferred_lcd_update(void); void gray_deferred_lcd_update(void);
void gray_screendump(void);
/* Update functions */ /* Update functions */
void gray_update(void); void gray_update(void);

View file

@ -36,6 +36,7 @@ short _gray_random_buffer; /* buffer for random number generator */
/* Prototypes */ /* Prototypes */
static void _timer_isr(void); static void _timer_isr(void);
static void gray_screendump_hook(int fd);
/* Timer interrupt handler: display next bitplane */ /* Timer interrupt handler: display next bitplane */
static void _timer_isr(void) static void _timer_isr(void)
@ -230,11 +231,13 @@ void gray_show(bool enable)
{ {
_gray_info.flags |= _GRAY_RUNNING; _gray_info.flags |= _GRAY_RUNNING;
_gray_rb->timer_register(1, NULL, FREQ / 67, 1, _timer_isr); _gray_rb->timer_register(1, NULL, FREQ / 67, 1, _timer_isr);
_gray_rb->screen_dump_set_hook(gray_screendump_hook);
} }
else else
{ {
_gray_rb->timer_unregister(); _gray_rb->timer_unregister();
_gray_info.flags &= ~_GRAY_RUNNING; _gray_info.flags &= ~_GRAY_RUNNING;
_gray_rb->screen_dump_set_hook(NULL);
_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) #elif defined(CPU_COLDFIRE) && (CONFIG_LCD == LCD_S1D15E06)
@ -244,12 +247,14 @@ void gray_show(bool enable)
_gray_rb->cpu_boost(true); /* run at 120 MHz to avoid freq changes */ _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, _gray_rb->timer_register(1, NULL, *_gray_rb->cpu_frequency / 70, 1,
_timer_isr); _timer_isr);
_gray_rb->screen_dump_set_hook(gray_screendump_hook);
} }
else if (!enable && (_gray_info.flags & _GRAY_RUNNING)) else if (!enable && (_gray_info.flags & _GRAY_RUNNING))
{ {
_gray_rb->timer_unregister(); _gray_rb->timer_unregister();
_gray_rb->cpu_boost(false); _gray_rb->cpu_boost(false);
_gray_info.flags &= ~_GRAY_RUNNING; _gray_info.flags &= ~_GRAY_RUNNING;
_gray_rb->screen_dump_set_hook(NULL);
_gray_rb->lcd_update(); /* restore whatever there was before */ _gray_rb->lcd_update(); /* restore whatever there was before */
} }
#endif #endif
@ -315,7 +320,7 @@ void gray_update_rect(int x, int y, int width, int height)
if (change != 0) if (change != 0)
{ {
unsigned char *addr, *end; unsigned char *addr, *end;
unsigned mask; unsigned mask, trash;
pat_ptr = &pat_stack[8]; pat_ptr = &pat_stack[8];
cbuf = _gray_info.cur_buffer + srcofs_row; cbuf = _gray_info.cur_buffer + srcofs_row;
@ -400,7 +405,7 @@ void gray_update_rect(int x, int y, int width, int height)
"mov.l @%[patp]+,r7\n" "mov.l @%[patp]+,r7\n"
"mov.l @%[patp]+,r8\n" "mov.l @%[patp]+,r8\n"
"mov.l @%[patp]+,r9\n" "mov.l @%[patp]+,r9\n"
"mov.l @%[patp]+,r10 \n" "mov.l @%[patp],%[rx] \n"
"tst %[mask],%[mask] \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 */
@ -420,7 +425,7 @@ void gray_update_rect(int x, int y, int width, int height)
"rotcl r0 \n" "rotcl r0 \n"
"shlr r9 \n" "shlr r9 \n"
"rotcl r0 \n" "rotcl r0 \n"
"shlr r10 \n" "shlr %[rx] \n"
"mov.b @%[addr],%[patp]\n" /* read old value */ "mov.b @%[addr],%[patp]\n" /* read old value */
"rotcl r0 \n" "rotcl r0 \n"
"and %[mask],%[patp] \n" /* mask out unneeded bits */ "and %[mask],%[patp] \n" /* mask out unneeded bits */
@ -448,7 +453,7 @@ void gray_update_rect(int x, int y, int width, int height)
"rotcl r0 \n" "rotcl r0 \n"
"shlr r9 \n" "shlr r9 \n"
"rotcl r0 \n" "rotcl r0 \n"
"shlr r10 \n" "shlr %[rx] \n"
"rotcl r0 \n" "rotcl r0 \n"
"mov.b r0,@%[addr] \n" /* store byte to bitplane */ "mov.b r0,@%[addr] \n" /* store byte to bitplane */
"add %[psiz],%[addr] \n" /* advance to next bitplane */ "add %[psiz],%[addr] \n" /* advance to next bitplane */
@ -457,14 +462,15 @@ void gray_update_rect(int x, int y, int width, int height)
".ur_end: \n" ".ur_end: \n"
: /* outputs */ : /* outputs */
[patp]"+r"(pat_ptr),
[addr]"+r"(addr), [addr]"+r"(addr),
[mask]"+r"(mask) [mask]"+r"(mask),
[rx] "=&r"(trash)
: /* inputs */ : /* inputs */
[psiz]"r"(_gray_info.plane_size),
[end] "r"(end), [end] "r"(end),
[psiz]"r"(_gray_info.plane_size) [patp]"[rx]"(pat_ptr)
: /* clobbers */ : /* clobbers */
"r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10" "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9"
); );
} }
#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) #elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2)
@ -496,7 +502,7 @@ void gray_update_rect(int x, int y, int width, int height)
if (change != 0) if (change != 0)
{ {
unsigned char *addr, *end; unsigned char *addr, *end;
unsigned mask; unsigned mask, trash;
pat_ptr = &pat_stack[8]; pat_ptr = &pat_stack[8];
cbuf = _gray_info.cur_buffer + srcofs_row; cbuf = _gray_info.cur_buffer + srcofs_row;
@ -567,7 +573,7 @@ void gray_update_rect(int x, int y, int width, int height)
/* 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 volatile ( asm volatile (
"movem.l (%[patp]),%%d2-%%d6/%%a0-%%a2 \n" "movem.l (%[patp]),%%d2-%%d6/%%a0-%%a1/%[ax] \n"
/* pop all 8 patterns */ /* pop all 8 patterns */
"not.l %[mask] \n" /* set mask -> keep mask */ "not.l %[mask] \n" /* set mask -> keep mask */
"and.l #0xFF,%[mask] \n" "and.l #0xFF,%[mask] \n"
@ -593,10 +599,10 @@ void gray_update_rect(int x, int y, int width, int height)
"lsr.l #1,%%d1 \n" "lsr.l #1,%%d1 \n"
"addx.l %%d0,%%d0 \n" "addx.l %%d0,%%d0 \n"
"move.l %%d1,%%a1 \n" "move.l %%d1,%%a1 \n"
"move.l %%a2,%%d1 \n" "move.l %[ax],%%d1 \n"
"lsr.l #1,%%d1 \n" "lsr.l #1,%%d1 \n"
"addx.l %%d0,%%d0 \n" "addx.l %%d0,%%d0 \n"
"move.l %%d1,%%a2 \n" "move.l %%d1,%[ax] \n"
"move.b (%[addr]),%%d1 \n" /* read old value */ "move.b (%[addr]),%%d1 \n" /* read old value */
"and.l %[mask],%%d1 \n" /* mask out unneeded bits */ "and.l %[mask],%%d1 \n" /* mask out unneeded bits */
@ -629,10 +635,10 @@ void gray_update_rect(int x, int y, int width, int height)
"lsr.l #1,%%d1 \n" "lsr.l #1,%%d1 \n"
"addx.l %%d0,%%d0 \n" "addx.l %%d0,%%d0 \n"
"move.l %%d1,%%a1 \n" "move.l %%d1,%%a1 \n"
"move.l %%a2,%%d1 \n" "move.l %[ax],%%d1 \n"
"lsr.l #1,%%d1 \n" "lsr.l #1,%%d1 \n"
"addx.l %%d0,%%d0 \n" "addx.l %%d0,%%d0 \n"
"move.l %%d1,%%a2 \n" "move.l %%d1,%[ax] \n"
"move.b %%d0,(%[addr]) \n" /* store byte to bitplane */ "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */
"add.l %[psiz],%[addr] \n" /* advance to next bitplane */ "add.l %[psiz],%[addr] \n" /* advance to next bitplane */
@ -642,13 +648,14 @@ void gray_update_rect(int x, int y, int width, int height)
".ur_end: \n" ".ur_end: \n"
: /* outputs */ : /* outputs */
[addr]"+a"(addr), [addr]"+a"(addr),
[mask]"+d"(mask) [mask]"+d"(mask),
[ax] "=&a"(trash)
: /* inputs */ : /* inputs */
[psiz]"a"(_gray_info.plane_size), [psiz]"a"(_gray_info.plane_size),
[end] "a"(end), [end] "a"(end),
[patp]"a"(pat_ptr) [patp]"[ax]"(pat_ptr)
: /* clobbers */ : /* clobbers */
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1", "a2" "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1"
); );
} }
#endif #endif
@ -692,12 +699,14 @@ void gray_deferred_lcd_update(void)
/*** Screenshot ***/ /*** Screenshot ***/
#define BMP_NUMCOLORS 33 #define BMP_FIXEDCOLORS (1 << LCD_DEPTH)
#define BMP_BPP 8 #define BMP_VARCOLORS 33
#define BMP_LINESIZE ((LCD_WIDTH + 3) & ~3) #define BMP_NUMCOLORS (BMP_FIXEDCOLORS + BMP_VARCOLORS)
#define BMP_HEADERSIZE (54 + 4 * BMP_NUMCOLORS) #define BMP_BPP 8
#define BMP_DATASIZE (BMP_LINESIZE * LCD_HEIGHT) #define BMP_LINESIZE ((LCD_WIDTH + 3) & ~3)
#define BMP_TOTALSIZE (BMP_HEADERSIZE + BMP_DATASIZE) #define BMP_HEADERSIZE (54 + 4 * BMP_NUMCOLORS)
#define BMP_DATASIZE (BMP_LINESIZE * LCD_HEIGHT)
#define BMP_TOTALSIZE (BMP_HEADERSIZE + BMP_DATASIZE)
#define LE16_CONST(x) (x)&0xff, ((x)>>8)&0xff #define LE16_CONST(x) (x)&0xff, ((x)>>8)&0xff
#define LE32_CONST(x) (x)&0xff, ((x)>>8)&0xff, ((x)>>16)&0xff, ((x)>>24)&0xff #define LE32_CONST(x) (x)&0xff, ((x)>>8)&0xff, ((x)>>16)&0xff, ((x)>>24)&0xff
@ -720,6 +729,17 @@ static const unsigned char bmpheader[] =
0xc4, 0x0e, 0x00, 0x00, /* Vertical resolution (pixels/meter) */ 0xc4, 0x0e, 0x00, 0x00, /* Vertical resolution (pixels/meter) */
LE32_CONST(BMP_NUMCOLORS), /* Number of used colours */ LE32_CONST(BMP_NUMCOLORS), /* Number of used colours */
LE32_CONST(BMP_NUMCOLORS), /* Number of important colours */ LE32_CONST(BMP_NUMCOLORS), /* Number of important colours */
/* Fixed colours */
#if LCD_DEPTH == 1
0x90, 0xee, 0x90, 0x00, /* Colour #0 */
0x00, 0x00, 0x00, 0x00 /* Colour #1 */
#elif LCD_DEPTH == 2
0xe6, 0xd8, 0xad, 0x00, /* Colour #0 */
0x99, 0x90, 0x73, 0x00, /* Colour #1 */
0x4c, 0x48, 0x39, 0x00, /* Colour #2 */
0x00, 0x00, 0x00, 0x00 /* Colour #3 */
#endif
}; };
#if LCD_DEPTH == 1 #if LCD_DEPTH == 1
@ -732,135 +752,131 @@ static const unsigned char bmpheader[] =
#define BMP_BLUE 0xe6 #define BMP_BLUE 0xe6
#endif #endif
static unsigned char linebuf[BMP_LINESIZE]; /* Hook function for core screen_dump() to save the current display
content (b&w and greyscale overlay) to an 8-bit BMP file. */
/* Save the current display content (b&w and greyscale overlay) to an 8-bit static void gray_screendump_hook(int fd)
* BMP file in the root directory. */
void gray_screendump(void)
{ {
int fh, i, bright; int i, idx;
int y; int x, y, by;
int gx, mask;
#if LCD_DEPTH == 1 #if LCD_DEPTH == 1
int x, by, mask; int gby;
int gx, gby; #elif LCD_DEPTH == 2
unsigned char *lcdptr, *grayptr, *grayptr2; int shift, gy;
#endif #endif
char filename[MAX_PATH]; unsigned char *clut_entry;
unsigned char *lcdptr;
unsigned char *grayptr, *grayptr2;
unsigned char linebuf[MAX(4*BMP_VARCOLORS,BMP_LINESIZE)];
#ifdef HAVE_RTC _gray_rb->write(fd, bmpheader, sizeof(bmpheader)); /* write header */
struct tm *tm = _gray_rb->get_time();
_gray_rb->snprintf(filename, MAX_PATH,
"/graydump %04d-%02d-%02d %02d-%02d-%02d.bmp",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
#else
{
DIR* dir;
int max_dump_file = 1; /* default to graydump_0001.bmp */
dir = _gray_rb->opendir("/");
if (dir) /* found */
{
/* Search for the highest screendump filename present,
increment behind that. So even with "holes"
(deleted files), the newest will always have the
highest number. */
while(true)
{
struct dirent* entry;
int curr_dump_file;
/* walk through the directory content */
entry = _gray_rb->readdir(dir);
if (!entry)
{
_gray_rb->closedir(dir);
break; /* end of dir */
}
if (_gray_rb->strncasecmp(entry->d_name, "graydump_", 9))
continue; /* no screendump file */
curr_dump_file = _gray_rb->atoi(&entry->d_name[9]);
if (curr_dump_file >= max_dump_file)
max_dump_file = curr_dump_file + 1;
}
}
_gray_rb->snprintf(filename, MAX_PATH, "/graydump_%04d.bmp",
max_dump_file);
}
#endif
fh = _gray_rb->creat(filename, O_WRONLY);
if (fh < 0)
return;
_gray_rb->write(fh, bmpheader, sizeof(bmpheader)); /* write header */
/* build clut */ /* build clut */
linebuf[3] = 0; _gray_rb->memset(linebuf, 0, 4*BMP_VARCOLORS);
clut_entry = linebuf;
for (i = 0; i < BMP_NUMCOLORS; i++) for (i = _gray_info.depth; i > 0; i--)
{ {
bright = MIN(i, _gray_info.depth); *clut_entry++ = MULU16(BMP_BLUE, i) / _gray_info.depth;
linebuf[0] = MULU16(BMP_BLUE, bright) / _gray_info.depth; *clut_entry++ = MULU16(BMP_GREEN, i) / _gray_info.depth;
linebuf[1] = MULU16(BMP_GREEN, bright) / _gray_info.depth; *clut_entry++ = MULU16(BMP_RED, i) / _gray_info.depth;
linebuf[2] = MULU16(BMP_RED, bright) / _gray_info.depth; clut_entry++;
_gray_rb->write(fh, linebuf, 4);
} }
_gray_rb->write(fd, linebuf, 4*BMP_VARCOLORS);
/* 8-bit BMP image goes bottom -> top */ /* BMP image goes bottom -> top */
for (y = LCD_HEIGHT - 1; y >= 0; y--) for (y = LCD_HEIGHT - 1; y >= 0; y--)
{ {
_gray_rb->memset(linebuf, BMP_NUMCOLORS-1, LCD_WIDTH); _gray_rb->memset(linebuf, 0, BMP_LINESIZE);
#if LCD_DEPTH == 1 #if LCD_DEPTH == 1
mask = 1 << (y & 7); mask = 1 << (y & (_PBLOCK-1));
by = y >> 3; by = y >> _PBLOCK_EXP;
lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by); lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by);
gby = by - _gray_info.by; gby = by - _gray_info.by;
if ((_gray_info.flags & _GRAY_RUNNING) if ((unsigned) gby < (unsigned) _gray_info.bheight)
&& (unsigned) gby < (unsigned) _gray_info.bheight) {
{
/* line contains greyscale (and maybe b&w) graphics */ /* line contains greyscale (and maybe b&w) graphics */
grayptr = _gray_info.plane_data + MULU16(_gray_info.width, gby); grayptr = _gray_info.plane_data + MULU16(_gray_info.width, gby);
for (x = 0; x < LCD_WIDTH; x++) for (x = 0; x < LCD_WIDTH; x++)
{ {
if (*lcdptr++ & mask)
linebuf[x] = 0;
gx = x - _gray_info.x; gx = x - _gray_info.x;
if ((unsigned)gx < (unsigned)_gray_info.width) if ((unsigned)gx < (unsigned)_gray_info.width)
{ {
bright = 0; idx = BMP_FIXEDCOLORS;
grayptr2 = grayptr + gx; grayptr2 = grayptr + gx;
for (i = 0; i < _gray_info.depth; i++) for (i = _gray_info.depth; i > 0; i--)
{ {
if (!(*grayptr2 & mask)) if (*grayptr2 & mask)
bright++; idx++;
grayptr2 += _gray_info.plane_size; grayptr2 += _gray_info.plane_size;
} }
linebuf[x] = bright; linebuf[x] = idx;
} }
else
{
linebuf[x] = (*lcdptr & mask) ? 1 : 0;
}
lcdptr++;
} }
} }
else else
{ {
/* line contains only b&w graphics */ /* line contains only b&w graphics */
for (x = 0; x < LCD_WIDTH; x++) for (x = 0; x < LCD_WIDTH; x++)
if (*lcdptr++ & mask) linebuf[x] = (*lcdptr++ & mask) ? 1 : 0;
linebuf[x] = 0;
} }
#elif LCD_DEPTH == 2 #elif LCD_DEPTH == 2
/* TODO */ shift = 2 * (y & 3);
by = y >> 2;
lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by);
gy = y - (_gray_info.by << _PBLOCK_EXP);
if ((unsigned)gy < (unsigned)_gray_info.height)
{
/* line contains greyscale (and maybe b&w) graphics */
mask = 1 << (gy & (_PBLOCK-1));
grayptr = _gray_info.plane_data
+ MULU16(_gray_info.width, gy >> _PBLOCK_EXP);
for (x = 0; x < LCD_WIDTH; x++)
{
gx = x - _gray_info.x;
if ((unsigned)gx < (unsigned)_gray_info.width)
{
idx = BMP_FIXEDCOLORS;
grayptr2 = grayptr + gx;
for (i = _gray_info.depth; i > 0; i--)
{
if (*grayptr2 & mask)
idx++;
grayptr2 += _gray_info.plane_size;
}
linebuf[x] = idx;
}
else
{
linebuf[x] = (*lcdptr >> shift) & 3;
}
lcdptr++;
}
}
else
{
/* line contains only b&w graphics */
for (x = 0; x < LCD_WIDTH; x++)
linebuf[x] = (*lcdptr++ >> shift) & 3;
}
#endif #endif
_gray_rb->write(fh, linebuf, sizeof(linebuf)); _gray_rb->write(fd, linebuf, BMP_LINESIZE);
} }
_gray_rb->close(fh);
} }
#endif /* HAVE_LCD_BITMAP */ #endif /* HAVE_LCD_BITMAP */

View file

@ -588,7 +588,7 @@ static void _writearray(unsigned char *address, const unsigned char *src,
unsigned long *pat_ptr = &pat_stack[8]; unsigned long *pat_ptr = &pat_stack[8];
const unsigned char *_src; const unsigned char *_src;
unsigned char *addr, *end; unsigned char *addr, *end;
unsigned _mask; unsigned _mask, trash;
_mask = mask; _mask = mask;
_src = src; _src = src;
@ -675,7 +675,7 @@ static void _writearray(unsigned char *address, const unsigned char *src,
"mov.l @%[patp]+,r7\n" "mov.l @%[patp]+,r7\n"
"mov.l @%[patp]+,r8\n" "mov.l @%[patp]+,r8\n"
"mov.l @%[patp]+,r9\n" "mov.l @%[patp]+,r9\n"
"mov.l @%[patp]+,r10 \n" "mov.l @%[patp],%[rx] \n"
"not %[mask],%[mask] \n" /* "set" mask -> "keep" mask */ "not %[mask],%[mask] \n" /* "set" mask -> "keep" mask */
"extu.b %[mask],%[mask] \n" /* mask out high bits */ "extu.b %[mask],%[mask] \n" /* mask out high bits */
@ -697,7 +697,7 @@ static void _writearray(unsigned char *address, const unsigned char *src,
"rotcl r0 \n" "rotcl r0 \n"
"shlr r9 \n" "shlr r9 \n"
"rotcl r0 \n" "rotcl r0 \n"
"shlr r10 \n" "shlr %[rx] \n"
"mov.b @%[addr],%[patp]\n" /* read old value */ "mov.b @%[addr],%[patp]\n" /* read old value */
"rotcl r0 \n" "rotcl r0 \n"
"and %[mask],%[patp] \n" /* mask out unneeded bits */ "and %[mask],%[patp] \n" /* mask out unneeded bits */
@ -725,7 +725,7 @@ static void _writearray(unsigned char *address, const unsigned char *src,
"rotcl r0 \n" "rotcl r0 \n"
"shlr r9 \n" "shlr r9 \n"
"rotcl r0 \n" "rotcl r0 \n"
"shlr r10 \n" "shlr %[rx] \n"
"rotcl r0 \n" "rotcl r0 \n"
"mov.b r0,@%[addr] \n" /* store byte to bitplane */ "mov.b r0,@%[addr] \n" /* store byte to bitplane */
"add %[psiz],%[addr] \n" /* advance to next bitplane */ "add %[psiz],%[addr] \n" /* advance to next bitplane */
@ -734,21 +734,22 @@ static void _writearray(unsigned char *address, const unsigned char *src,
".wa_end: \n" ".wa_end: \n"
: /* outputs */ : /* outputs */
[patp]"+r"(pat_ptr),
[addr]"+r"(addr), [addr]"+r"(addr),
[mask]"+r"(_mask) [mask]"+r"(_mask),
[rx] "=&r"(trash)
: /* inputs */ : /* inputs */
[psiz]"r"(_gray_info.plane_size),
[end] "r"(end), [end] "r"(end),
[psiz]"r"(_gray_info.plane_size) [patp]"[rx]"(pat_ptr)
: /* clobbers */ : /* clobbers */
"r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10" "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9"
); );
#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) #elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2)
unsigned long pat_stack[8]; unsigned long pat_stack[8];
unsigned long *pat_ptr = &pat_stack[8]; unsigned long *pat_ptr = &pat_stack[8];
const unsigned char *_src; const unsigned char *_src;
unsigned char *addr, *end; unsigned char *addr, *end;
unsigned _mask; unsigned _mask, trash;
_mask = mask; _mask = mask;
_src = src; _src = src;
@ -819,8 +820,8 @@ static void _writearray(unsigned char *address, const unsigned char *src,
/* 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 volatile ( asm volatile (
"movem.l (%[patp]),%%d2-%%d6/%%a0-%%a2 \n" /* pop all 8 patterns */ "movem.l (%[patp]),%%d2-%%d6/%%a0-%%a1/%[ax] \n"
/* pop all 8 patterns */
"not.l %[mask] \n" /* "set" mask -> "keep" mask */ "not.l %[mask] \n" /* "set" mask -> "keep" mask */
"and.l #0xFF,%[mask] \n" "and.l #0xFF,%[mask] \n"
"beq.b .wa_sloop \n" /* yes: jump to short loop */ "beq.b .wa_sloop \n" /* yes: jump to short loop */
@ -845,10 +846,10 @@ static void _writearray(unsigned char *address, const unsigned char *src,
"lsr.l #1,%%d1 \n" "lsr.l #1,%%d1 \n"
"addx.l %%d0,%%d0 \n" "addx.l %%d0,%%d0 \n"
"move.l %%d1,%%a1 \n" "move.l %%d1,%%a1 \n"
"move.l %%a2,%%d1 \n" "move.l %[ax],%%d1 \n"
"lsr.l #1,%%d1 \n" "lsr.l #1,%%d1 \n"
"addx.l %%d0,%%d0 \n" "addx.l %%d0,%%d0 \n"
"move.l %%d1,%%a2 \n" "move.l %%d1,%[ax] \n"
"move.b (%[addr]),%%d1 \n" /* read old value */ "move.b (%[addr]),%%d1 \n" /* read old value */
"and.l %[mask],%%d1 \n" /* mask out unneeded bits */ "and.l %[mask],%%d1 \n" /* mask out unneeded bits */
@ -881,10 +882,10 @@ static void _writearray(unsigned char *address, const unsigned char *src,
"lsr.l #1,%%d1 \n" "lsr.l #1,%%d1 \n"
"addx.l %%d0,%%d0 \n" "addx.l %%d0,%%d0 \n"
"move.l %%d1,%%a1 \n" "move.l %%d1,%%a1 \n"
"move.l %%a2,%%d1 \n" "move.l %[ax],%%d1 \n"
"lsr.l #1,%%d1 \n" "lsr.l #1,%%d1 \n"
"addx.l %%d0,%%d0 \n" "addx.l %%d0,%%d0 \n"
"move.l %%d1,%%a2 \n" "move.l %%d1,%[ax] \n"
"move.b %%d0,(%[addr]) \n" /* store byte to bitplane */ "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */
"add.l %[psiz],%[addr] \n" /* advance to next bitplane */ "add.l %[psiz],%[addr] \n" /* advance to next bitplane */
@ -894,13 +895,14 @@ static void _writearray(unsigned char *address, const unsigned char *src,
".wa_end: \n" ".wa_end: \n"
: /* outputs */ : /* outputs */
[addr]"+a"(addr), [addr]"+a"(addr),
[mask]"+d"(_mask) [mask]"+d"(_mask),
[ax] "=&a"(trash)
: /* inputs */ : /* inputs */
[psiz]"a"(_gray_info.plane_size), [psiz]"a"(_gray_info.plane_size),
[end] "a"(end), [end] "a"(end),
[patp]"a"(pat_ptr) [patp]"[ax]"(pat_ptr)
: /* clobbers */ : /* clobbers */
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1", "a2" "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1"
); );
#endif #endif
} }