1
0
Fork 0
forked from len0rd/rockbox

LCd extension lib: Implement proper scrolling for 2 bit vertical interleaved LCD. Stops oscilloscope from crashing on M3. * A few small simplifications.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16754 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2008-03-23 00:28:16 +00:00
parent ad6cbbdd3c
commit e03ef1ec23

View file

@ -25,6 +25,10 @@
#ifdef HAVE_LCD_BITMAP
#include "xlcd.h"
#if (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
static const unsigned short patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000};
#endif
#if (LCD_PIXELFORMAT == HORIZONTAL_PACKING) && (LCD_DEPTH < 8)
/* Scroll left */
@ -149,11 +153,7 @@ void xlcd_scroll_left(int count)
return;
data = _xlcd_rb->lcd_framebuffer;
#if LCD_DEPTH >= 8
data_end = data + LCD_WIDTH*LCD_HEIGHT;
#else
data_end = data + LCD_WIDTH*((LCD_HEIGHT*LCD_DEPTH+7)/8);
#endif
data_end = data + LCD_WIDTH*LCD_FBHEIGHT;
length = LCD_WIDTH - count;
do
@ -179,11 +179,7 @@ void xlcd_scroll_right(int count)
return;
data = _xlcd_rb->lcd_framebuffer;
#if LCD_DEPTH >= 8
data_end = data + LCD_WIDTH*LCD_HEIGHT;
#else
data_end = data + LCD_WIDTH*((LCD_HEIGHT*LCD_DEPTH+7)/8);
#endif
data_end = data + LCD_WIDTH*LCD_FBHEIGHT;
length = LCD_WIDTH - count;
do
@ -243,7 +239,8 @@ void xlcd_scroll_down(int count)
_xlcd_rb->lcd_set_drawmode(oldmode);
}
#else /* LCD_PIXELFORMAT vertical packed */
#else /* LCD_PIXELFORMAT == VERTICAL_PACKING,
LCD_PIXELFORMAT == VERTICAL_INTERLEAVED */
/* Scroll up */
void xlcd_scroll_up(int count)
@ -254,24 +251,26 @@ void xlcd_scroll_up(int count)
if ((unsigned) count >= LCD_HEIGHT)
return;
#if LCD_DEPTH == 1
#if (LCD_DEPTH == 1) \
|| (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
blockcount = count >> 3;
blocklen = ((LCD_HEIGHT+7)/8) - blockcount;
bitcount = count & 7;
#elif LCD_DEPTH == 2
#elif (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_PACKING)
blockcount = count >> 2;
blocklen = ((LCD_HEIGHT+3)/4) - blockcount;
bitcount = 2 * (count & 3);
#endif
blocklen = LCD_FBHEIGHT - blockcount;
if (blockcount)
{
_xlcd_rb->memmove(_xlcd_rb->lcd_framebuffer,
_xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH,
blocklen * LCD_FBWIDTH);
blocklen * LCD_FBWIDTH * sizeof(fb_data));
}
if (bitcount)
{
#if LCD_PIXELFORMAT == VERTICAL_PACKING
#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
asm (
"mov #0,r4 \n" /* x = 0 */
@ -384,17 +383,15 @@ void xlcd_scroll_up(int count)
unsigned char *addr = _xlcd_rb->lcd_framebuffer + blocklen * LCD_FBWIDTH;
#if LCD_DEPTH == 2
unsigned fill = 0x55 * (~_xlcd_rb->lcd_get_background() & 3);
#else
const unsigned fill = 0;
#endif
for (x = 0; x < LCD_WIDTH; x++)
{
unsigned char *col_addr = addr++;
#if LCD_DEPTH == 1
unsigned data = 0;
#else
unsigned data = fill;
#endif
for (by = 0; by < blocklen; by++)
{
col_addr -= LCD_FBWIDTH;
@ -403,6 +400,35 @@ void xlcd_scroll_up(int count)
}
}
#endif /* CPU, LCD_DEPTH */
#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
#if LCD_DEPTH == 2
int x, by;
fb_data *addr = _xlcd_rb->lcd_framebuffer + blocklen * LCD_FBWIDTH;
unsigned fill, mask;
fill = patterns[_xlcd_rb->lcd_get_background() & 3] << 8;
mask = (0xFFu >> bitcount) << bitcount;
mask |= mask << 8;
for (x = 0; x < LCD_WIDTH; x++)
{
fb_data *col_addr = addr++;
unsigned olddata = fill;
unsigned data;
for (by = 0; by < blocklen; by++)
{
col_addr -= LCD_FBWIDTH;
data = *col_addr;
*col_addr = (olddata ^ ((data ^ olddata) & mask)) >> bitcount;
olddata = data << 8;
}
}
#endif /* LCD_DEPTH == 2 */
#endif /* LCD_PIXELFORMAT */
}
oldmode = _xlcd_rb->lcd_get_drawmode();
_xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
@ -419,24 +445,26 @@ void xlcd_scroll_down(int count)
if ((unsigned) count >= LCD_HEIGHT)
return;
#if LCD_DEPTH == 1
#if (LCD_DEPTH == 1) \
|| (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
blockcount = count >> 3;
blocklen = ((LCD_HEIGHT+7)/8) - blockcount;
bitcount = count & 7;
#elif LCD_DEPTH == 2
#elif (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_PACKING)
blockcount = count >> 2;
blocklen = ((LCD_HEIGHT+3)/4) - blockcount;
bitcount = 2 * (count & 3);
#endif
blocklen = LCD_FBHEIGHT - blockcount;
if (blockcount)
{
_xlcd_rb->memmove(_xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH,
_xlcd_rb->lcd_framebuffer,
blocklen * LCD_FBWIDTH);
blocklen * LCD_FBWIDTH * sizeof(fb_data));
}
if (bitcount)
{
#if LCD_PIXELFORMAT == VERTICAL_PACKING
#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
asm (
"mov #0,r4 \n" /* x = 0 */
@ -545,17 +573,15 @@ void xlcd_scroll_down(int count)
unsigned char *addr = _xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH;
#if LCD_DEPTH == 2
unsigned fill = (0x55 * (~_xlcd_rb->lcd_get_background() & 3)) << bitcount;
#else
const unsigned fill = 0;
#endif
for (x = 0; x < LCD_WIDTH; x++)
{
unsigned char *col_addr = addr++;
#if LCD_DEPTH == 1
unsigned data = 0;
#else
unsigned data = fill;
#endif
for (by = 0; by < blocklen; by++)
{
data = (data >> 8) | (*col_addr << bitcount);
@ -564,6 +590,35 @@ void xlcd_scroll_down(int count)
}
}
#endif /* CPU, LCD_DEPTH */
#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
#if LCD_DEPTH == 2
int x, by;
fb_data *addr = _xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH;
unsigned fill, mask;
fill = patterns[_xlcd_rb->lcd_get_background() & 3] >> (8 - bitcount);
mask = (0xFFu >> bitcount) << bitcount;
mask |= mask << 8;
for (x = 0; x < LCD_WIDTH; x++)
{
fb_data *col_addr = addr++;
unsigned olddata = fill;
unsigned data;
for (by = 0; by < blocklen; by++)
{
data = *col_addr << bitcount;
*col_addr = olddata ^ ((data ^ olddata) & mask);
olddata = data >> 8;
col_addr += LCD_FBWIDTH;
}
}
#endif /* LCD_DEPTH == 2 */
#endif /* LCD_PIXELFORMAT */
}
oldmode = _xlcd_rb->lcd_get_drawmode();
_xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);