summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/lib/SOURCES4
-rw-r--r--apps/plugins/lib/xlcd.h3
-rw-r--r--apps/plugins/lib/xlcd_core.c41
-rwxr-xr-xapps/plugins/lib/xlcd_draw.c379
-rwxr-xr-xapps/plugins/lib/xlcd_scroll.c576
-rw-r--r--apps/plugins/oscilloscope.c69
-rw-r--r--firmware/drivers/lcd-2bit-horz.c18
-rw-r--r--firmware/export/lcd.h8
8 files changed, 1026 insertions, 72 deletions
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES
index 6bcddbab96..f0930269f7 100644
--- a/apps/plugins/lib/SOURCES
+++ b/apps/plugins/lib/SOURCES
@@ -16,5 +16,7 @@ playergfx.c
profile_plugin.c
#endif
#ifdef HAVE_LCD_BITMAP
-xlcd.c
+xlcd_core.c
+xlcd_draw.c
+xlcd_scroll.c
#endif
diff --git a/apps/plugins/lib/xlcd.h b/apps/plugins/lib/xlcd.h
index 8f3071443e..473c51c732 100644
--- a/apps/plugins/lib/xlcd.h
+++ b/apps/plugins/lib/xlcd.h
@@ -47,6 +47,9 @@ void xlcd_scroll_right(int count);
void xlcd_scroll_up(int count);
void xlcd_scroll_down(int count);
+/* internal stuff */
+extern struct plugin_api *_xlcd_rb; /* global api struct pointer */
+
#endif /* HAVE_LCD_BITMAP */
#endif /* __XLCD_H__ */
diff --git a/apps/plugins/lib/xlcd_core.c b/apps/plugins/lib/xlcd_core.c
new file mode 100644
index 0000000000..e8cc688591
--- /dev/null
+++ b/apps/plugins/lib/xlcd_core.c
@@ -0,0 +1,41 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* Additional LCD routines not present in the rockbox core
+* Core functions
+*
+* Copyright (C) 2005 Jens Arnold
+*
+* All files in this archive are subject to the GNU General Public License.
+* See the file COPYING in the source tree root for full license agreement.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+
+#include "plugin.h"
+
+#ifdef HAVE_LCD_BITMAP
+#include "xlcd.h"
+
+/*** globals ***/
+
+struct plugin_api *_xlcd_rb = NULL; /* global api struct pointer */
+
+/*** functions ***/
+
+/* library init */
+void xlcd_init(struct plugin_api* newrb)
+{
+ _xlcd_rb = newrb;
+}
+
+#endif /* HAVE_LCD_BITMAP */
+
diff --git a/apps/plugins/lib/xlcd_draw.c b/apps/plugins/lib/xlcd_draw.c
new file mode 100755
index 0000000000..3ccdea9139
--- /dev/null
+++ b/apps/plugins/lib/xlcd_draw.c
@@ -0,0 +1,379 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* Additional LCD routines not present in the rockbox core
+* Drawing functions
+*
+* Copyright (C) 2005 Jens Arnold
+*
+* All files in this archive are subject to the GNU General Public License.
+* See the file COPYING in the source tree root for full license agreement.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+
+#include "plugin.h"
+
+#ifdef HAVE_LCD_BITMAP
+#include "xlcd.h"
+
+#if (LCD_DEPTH >= 8) || (LCD_PIXELFORMAT == HORIZONTAL_PACKING)
+/* draw a filled triangle, using horizontal lines for speed */
+void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
+{
+ int x, y;
+ long fp_x1, fp_x2, fp_dx1, fp_dx2;
+
+ /* sort vertices by increasing y value */
+ if (y1 > y3)
+ {
+ if (y2 < y3) /* y2 < y3 < y1 */
+ {
+ x = x1; x1 = x2; x2 = x3; x3 = x;
+ y = y1; y1 = y2; y2 = y3; y3 = y;
+ }
+ else if (y2 > y1) /* y3 < y1 < y2 */
+ {
+ x = x1; x1 = x3; x3 = x2; x2 = x;
+ y = y1; y1 = y3; y3 = y2; y2 = y;
+ }
+ else /* y3 <= y2 <= y1 */
+ {
+ x = x1; x1 = x3; x3 = x;
+ y = y1; y1 = y3; y3 = y;
+ }
+ }
+ else
+ {
+ if (y2 < y1) /* y2 < y1 <= y3 */
+ {
+ x = x1; x1 = x2; x2 = x;
+ y = y1; y1 = y2; y2 = y;
+ }
+ else if (y2 > y3) /* y1 <= y3 < y2 */
+ {
+ x = x2; x2 = x3; x3 = x;
+ y = y2; y2 = y3; y3 = y;
+ }
+ /* else already sorted */
+ }
+
+ if (y1 < y3) /* draw */
+ {
+ fp_dx1 = ((x3 - x1) << 16) / (y3 - y1);
+ fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1);
+
+ if (y1 < y2) /* first part */
+ {
+ fp_dx2 = ((x2 - x1) << 16) / (y2 - y1);
+ fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1);
+ for (y = y1; y < y2; y++)
+ {
+ _xlcd_rb->lcd_hline(fp_x1 >> 16, fp_x2 >> 16, y);
+ fp_x1 += fp_dx1;
+ fp_x2 += fp_dx2;
+ }
+ }
+ if (y2 < y3) /* second part */
+ {
+ fp_dx2 = ((x3 - x2) << 16) / (y3 - y2);
+ fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1);
+ for (y = y2; y < y3; y++)
+ {
+ _xlcd_rb->lcd_hline(fp_x1 >> 16, fp_x2 >> 16, y);
+ fp_x1 += fp_dx1;
+ fp_x2 += fp_dx2;
+ }
+ }
+ }
+}
+#else /* (LCD_DEPTH < 8) && (LCD_PIXELFORMAT == VERTICAL_PACKING) */
+/* draw a filled triangle, using vertical lines for speed */
+void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
+{
+ int x, y;
+ long fp_y1, fp_y2, fp_dy1, fp_dy2;
+
+ /* sort vertices by increasing x value */
+ if (x1 > x3)
+ {
+ if (x2 < x3) /* x2 < x3 < x1 */
+ {
+ x = x1; x1 = x2; x2 = x3; x3 = x;
+ y = y1; y1 = y2; y2 = y3; y3 = y;
+ }
+ else if (x2 > x1) /* x3 < x1 < x2 */
+ {
+ x = x1; x1 = x3; x3 = x2; x2 = x;
+ y = y1; y1 = y3; y3 = y2; y2 = y;
+ }
+ else /* x3 <= x2 <= x1 */
+ {
+ x = x1; x1 = x3; x3 = x;
+ y = y1; y1 = y3; y3 = y;
+ }
+ }
+ else
+ {
+ if (x2 < x1) /* x2 < x1 <= x3 */
+ {
+ x = x1; x1 = x2; x2 = x;
+ y = y1; y1 = y2; y2 = y;
+ }
+ else if (x2 > x3) /* x1 <= x3 < x2 */
+ {
+ x = x2; x2 = x3; x3 = x;
+ y = y2; y2 = y3; y3 = y;
+ }
+ /* else already sorted */
+ }
+
+ if (x1 < x3) /* draw */
+ {
+ fp_dy1 = ((y3 - y1) << 16) / (x3 - x1);
+ fp_y1 = (y1 << 16) + (1<<15) + (fp_dy1 >> 1);
+
+ if (x1 < x2) /* first part */
+ {
+ fp_dy2 = ((y2 - y1) << 16) / (x2 - x1);
+ fp_y2 = (y1 << 16) + (1<<15) + (fp_dy2 >> 1);
+ for (x = x1; x < x2; x++)
+ {
+ _xlcd_rb->lcd_vline(x, fp_y1 >> 16, fp_y2 >> 16);
+ fp_y1 += fp_dy1;
+ fp_y2 += fp_dy2;
+ }
+ }
+ if (x2 < x3) /* second part */
+ {
+ fp_dy2 = ((y3 - y2) << 16) / (x3 - x2);
+ fp_y2 = (y2 << 16) + (1<<15) + (fp_dy2 >> 1);
+ for (x = x2; x < x3; x++)
+ {
+ _xlcd_rb->lcd_vline(x, fp_y1 >> 16, fp_y2 >> 16);
+ fp_y1 += fp_dy1;
+ fp_y2 += fp_dy2;
+ }
+ }
+ }
+}
+#endif /* LCD_DEPTH, LCD_PIXELFORMAT */
+
+#if LCD_DEPTH >= 8
+
+#ifdef HAVE_LCD_COLOR
+static const fb_data graylut[256] = {
+#if LCD_PIXELFORMAT == RGB565
+ 0x0000, 0x0000, 0x0000, 0x0020, 0x0020, 0x0821, 0x0821, 0x0841,
+ 0x0841, 0x0841, 0x0841, 0x0861, 0x0861, 0x1062, 0x1062, 0x1082,
+ 0x1082, 0x1082, 0x1082, 0x10a2, 0x10a2, 0x18a3, 0x18a3, 0x18c3,
+ 0x18c3, 0x18c3, 0x18c3, 0x18e3, 0x18e3, 0x20e4, 0x20e4, 0x2104,
+ 0x2104, 0x2104, 0x2104, 0x2124, 0x2124, 0x2124, 0x2925, 0x2945,
+ 0x2945, 0x2945, 0x2945, 0x2965, 0x2965, 0x2965, 0x3166, 0x3186,
+ 0x3186, 0x3186, 0x3186, 0x31a6, 0x31a6, 0x31a6, 0x39a7, 0x39c7,
+ 0x39c7, 0x39c7, 0x39c7, 0x39e7, 0x39e7, 0x39e7, 0x41e8, 0x4208,
+ 0x4208, 0x4208, 0x4208, 0x4228, 0x4228, 0x4228, 0x4a29, 0x4a49,
+ 0x4a49, 0x4a49, 0x4a49, 0x4a69, 0x4a69, 0x4a69, 0x4a69, 0x528a,
+ 0x528a, 0x528a, 0x528a, 0x52aa, 0x52aa, 0x52aa, 0x52aa, 0x5aab,
+ 0x5acb, 0x5acb, 0x5acb, 0x5acb, 0x5aeb, 0x5aeb, 0x5aeb, 0x62ec,
+ 0x630c, 0x630c, 0x630c, 0x630c, 0x632c, 0x632c, 0x632c, 0x6b2d,
+ 0x6b4d, 0x6b4d, 0x6b4d, 0x6b4d, 0x6b6d, 0x6b6d, 0x6b6d, 0x6b6d,
+ 0x738e, 0x738e, 0x738e, 0x738e, 0x73ae, 0x73ae, 0x73ae, 0x73ae,
+ 0x7bcf, 0x7bcf, 0x7bcf, 0x7bcf, 0x7bef, 0x7bef, 0x7bef, 0x7bef,
+ 0x8410, 0x8410, 0x8410, 0x8410, 0x8430, 0x8430, 0x8430, 0x8430,
+ 0x8c51, 0x8c51, 0x8c51, 0x8c51, 0x8c71, 0x8c71, 0x8c71, 0x8c71,
+ 0x9492, 0x9492, 0x9492, 0x9492, 0x94b2, 0x94b2, 0x94b2, 0x94b2,
+ 0x94d2, 0x9cd3, 0x9cd3, 0x9cd3, 0x9cf3, 0x9cf3, 0x9cf3, 0x9cf3,
+ 0x9d13, 0xa514, 0xa514, 0xa514, 0xa534, 0xa534, 0xa534, 0xa534,
+ 0xa554, 0xad55, 0xad55, 0xad55, 0xad55, 0xad75, 0xad75, 0xad75,
+ 0xad75, 0xb596, 0xb596, 0xb596, 0xb596, 0xb5b6, 0xb5b6, 0xb5b6,
+ 0xb5b6, 0xb5d6, 0xbdd7, 0xbdd7, 0xbdd7, 0xbdf7, 0xbdf7, 0xbdf7,
+ 0xbdf7, 0xbe17, 0xc618, 0xc618, 0xc618, 0xc638, 0xc638, 0xc638,
+ 0xc638, 0xc658, 0xce59, 0xce59, 0xce59, 0xce79, 0xce79, 0xce79,
+ 0xce79, 0xce99, 0xd69a, 0xd69a, 0xd69a, 0xd6ba, 0xd6ba, 0xd6ba,
+ 0xd6ba, 0xd6da, 0xd6da, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xdefb,
+ 0xdefb, 0xdf1b, 0xdf1b, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xe73c,
+ 0xe73c, 0xe75c, 0xe75c, 0xef5d, 0xef5d, 0xef7d, 0xef7d, 0xef7d,
+ 0xef7d, 0xef9d, 0xef9d, 0xf79e, 0xf79e, 0xf7be, 0xf7be, 0xf7be,
+ 0xf7be, 0xf7de, 0xf7de, 0xffdf, 0xffdf, 0xffff, 0xffff, 0xffff
+#elif LCD_PIXELFORMAT == RGB565SWAPPED
+ 0x0000, 0x0000, 0x0000, 0x2000, 0x2000, 0x2108, 0x2108, 0x4108,
+ 0x4108, 0x4108, 0x4108, 0x6108, 0x6108, 0x6210, 0x6210, 0x8210,
+ 0x8210, 0x8210, 0x8210, 0xa210, 0xa210, 0xa318, 0xa318, 0xc318,
+ 0xc318, 0xc318, 0xc318, 0xe318, 0xe318, 0xe420, 0xe420, 0x0421,
+ 0x0421, 0x0421, 0x0421, 0x2421, 0x2421, 0x2421, 0x2529, 0x4529,
+ 0x4529, 0x4529, 0x4529, 0x6529, 0x6529, 0x6529, 0x6631, 0x8631,
+ 0x8631, 0x8631, 0x8631, 0xa631, 0xa631, 0xa631, 0xa739, 0xc739,
+ 0xc739, 0xc739, 0xc739, 0xe739, 0xe739, 0xe739, 0xe841, 0x0842,
+ 0x0842, 0x0842, 0x0842, 0x2842, 0x2842, 0x2842, 0x294a, 0x494a,
+ 0x494a, 0x494a, 0x494a, 0x694a, 0x694a, 0x694a, 0x694a, 0x8a52,
+ 0x8a52, 0x8a52, 0x8a52, 0xaa52, 0xaa52, 0xaa52, 0xaa52, 0xab5a,
+ 0xcb5a, 0xcb5a, 0xcb5a, 0xcb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xec62,
+ 0x0c63, 0x0c63, 0x0c63, 0x0c63, 0x2c63, 0x2c63, 0x2c63, 0x2d6b,
+ 0x4d6b, 0x4d6b, 0x4d6b, 0x4d6b, 0x6d6b, 0x6d6b, 0x6d6b, 0x6d6b,
+ 0x8e73, 0x8e73, 0x8e73, 0x8e73, 0xae73, 0xae73, 0xae73, 0xae73,
+ 0xcf7b, 0xcf7b, 0xcf7b, 0xcf7b, 0xef7b, 0xef7b, 0xef7b, 0xef7b,
+ 0x1084, 0x1084, 0x1084, 0x1084, 0x3084, 0x3084, 0x3084, 0x3084,
+ 0x518c, 0x518c, 0x518c, 0x518c, 0x718c, 0x718c, 0x718c, 0x718c,
+ 0x9294, 0x9294, 0x9294, 0x9294, 0xb294, 0xb294, 0xb294, 0xb294,
+ 0xd294, 0xd39c, 0xd39c, 0xd39c, 0xf39c, 0xf39c, 0xf39c, 0xf39c,
+ 0x139d, 0x14a5, 0x14a5, 0x14a5, 0x34a5, 0x34a5, 0x34a5, 0x34a5,
+ 0x54a5, 0x55ad, 0x55ad, 0x55ad, 0x55ad, 0x75ad, 0x75ad, 0x75ad,
+ 0x75ad, 0x96b5, 0x96b5, 0x96b5, 0x96b5, 0xb6b5, 0xb6b5, 0xb6b5,
+ 0xb6b5, 0xd6b5, 0xd7bd, 0xd7bd, 0xd7bd, 0xf7bd, 0xf7bd, 0xf7bd,
+ 0xf7bd, 0x17be, 0x18c6, 0x18c6, 0x18c6, 0x38c6, 0x38c6, 0x38c6,
+ 0x38c6, 0x58c6, 0x59ce, 0x59ce, 0x59ce, 0x79ce, 0x79ce, 0x79ce,
+ 0x79ce, 0x99ce, 0x9ad6, 0x9ad6, 0x9ad6, 0xbad6, 0xbad6, 0xbad6,
+ 0xbad6, 0xdad6, 0xdad6, 0xdbde, 0xdbde, 0xfbde, 0xfbde, 0xfbde,
+ 0xfbde, 0x1bdf, 0x1bdf, 0x1ce7, 0x1ce7, 0x3ce7, 0x3ce7, 0x3ce7,
+ 0x3ce7, 0x5ce7, 0x5ce7, 0x5def, 0x5def, 0x7def, 0x7def, 0x7def,
+ 0x7def, 0x9def, 0x9def, 0x9ef7, 0x9ef7, 0xbef7, 0xbef7, 0xbef7,
+ 0xbef7, 0xdef7, 0xdef7, 0xdfff, 0xdfff, 0xffff, 0xffff, 0xffff
+#endif /* LCD_PIXELFORMAT */
+};
+#endif /* HAVE_LCD_COLOR */
+
+/* Draw a partial greyscale bitmap, canonical 8 bit format */
+void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
+ int stride, int x, int y, int width, int height)
+{
+ const unsigned char *src_end;
+ fb_data *dst;
+
+ /* nothing to draw? */
+ if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
+ || (x + width <= 0) || (y + height <= 0))
+ return;
+
+ /* clipping */
+ if (x < 0)
+ {
+ width += x;
+ src_x -= x;
+ x = 0;
+ }
+ if (y < 0)
+ {
+ height += y;
+ src_y -= y;
+ y = 0;
+ }
+ if (x + width > LCD_WIDTH)
+ width = LCD_WIDTH - x;
+ if (y + height > LCD_HEIGHT)
+ height = LCD_HEIGHT - y;
+
+ src += stride * src_y + src_x; /* move starting point */
+ src_end = src + stride * height;
+ dst = _xlcd_rb->lcd_framebuffer + LCD_WIDTH * y + x;
+
+ do
+ {
+ const unsigned char *src_row = src;
+ const unsigned char *row_end = src_row + width;
+ fb_data *dst_row = dst;
+
+#ifdef HAVE_LCD_COLOR
+ do
+ *dst_row++ = graylut[*src_row++];
+ while (src_row < row_end);
+#endif
+
+ src += stride;
+ dst += LCD_WIDTH;
+ }
+ while (src < src_end);
+}
+
+/* Draw a full greyscale bitmap, canonical 8 bit format */
+void xlcd_gray_bitmap(const unsigned char *src, int x, int y, int width,
+ int height)
+{
+ xlcd_gray_bitmap_part(src, 0, 0, width, x, y, width, height);
+}
+
+#ifdef HAVE_LCD_COLOR
+/* Draw a partial colour bitmap, canonical 24 bit RGB format */
+void xlcd_color_bitmap_part(const unsigned char *src, int src_x, int src_y,
+ int stride, int x, int y, int width, int height)
+{
+ const unsigned char *src_end;
+ fb_data *dst;
+
+ /* nothing to draw? */
+ if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
+ || (x + width <= 0) || (y + height <= 0))
+ return;
+
+ /* clipping */
+ if (x < 0)
+ {
+ width += x;
+ src_x -= x;
+ x = 0;
+ }
+ if (y < 0)
+ {
+ height += y;
+ src_y -= y;
+ y = 0;
+ }
+ if (x + width > LCD_WIDTH)
+ width = LCD_WIDTH - x;
+ if (y + height > LCD_HEIGHT)
+ height = LCD_HEIGHT - y;
+
+ src += 3 * (stride * src_y + src_x); /* move starting point */
+ src_end = src + 3 * stride * height;
+ dst = _xlcd_rb->lcd_framebuffer + LCD_WIDTH * y + x;
+
+ do
+ {
+ const unsigned char *src_row = src;
+ const unsigned char *row_end = src_row + 3 * width;
+ fb_data *dst_row = dst;
+
+ do
+ { /* only RGB565 and RGB565SWAPPED so far */
+ unsigned red = 31 * (*src_row++) + 127;
+ unsigned green = 63 * (*src_row++) + 127;
+ unsigned blue = 31 * (*src_row++) + 127;
+
+ red = (red + (red >> 8)) >> 8; /* approx red /= 255: */
+ green = (green + (green >> 8)) >> 8; /* approx green /= 255: */
+ blue = (blue + (blue >> 8)) >> 8; /* approx blue /= 255: */
+
+#if LCD_PIXELFORMAT == RGB565
+ *dst_row++ = (red << 11) | (green << 5) | blue;
+#elif LCD_PIXELFORMAT == RGB565SWAPPED
+ *dst_row++ = swap16((red << 11) | (green << 5) | blue);
+#endif
+ }
+ while (src_row < row_end);
+
+ src += 3 * stride;
+ dst += LCD_WIDTH;
+ }
+ while (src < src_end);
+}
+
+/* Draw a full colour bitmap, canonical 24 bit RGB format */
+void xlcd_color_bitmap(const unsigned char *src, int x, int y, int width,
+ int height)
+{
+ xlcd_color_bitmap_part(src, 0, 0, width, x, y, width, height);
+}
+#endif /* HAVE_LCD_COLOR */
+
+#endif /* LCD_DEPTH >= 8 */
+
+#endif /* HAVE_LCD_BITMAP */
+
diff --git a/apps/plugins/lib/xlcd_scroll.c b/apps/plugins/lib/xlcd_scroll.c
new file mode 100755
index 0000000000..44117b452c
--- /dev/null
+++ b/apps/plugins/lib/xlcd_scroll.c
@@ -0,0 +1,576 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* Additional LCD routines not present in the rockbox core
+* Scrolling functions
+*
+* Copyright (C) 2005 Jens Arnold
+*
+* All files in this archive are subject to the GNU General Public License.
+* See the file COPYING in the source tree root for full license agreement.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+
+#include "plugin.h"
+
+#ifdef HAVE_LCD_BITMAP
+#include "xlcd.h"
+
+#if (LCD_PIXELFORMAT == HORIZONTAL_PACKING) && (LCD_DEPTH < 8)
+
+/* Scroll left */
+void xlcd_scroll_left(int count)
+{
+ int bitcount, oldmode;
+ int blockcount, blocklen;
+
+ if ((unsigned) count >= LCD_WIDTH)
+ return;
+
+#if LCD_DEPTH == 2
+ blockcount = count >> 2;
+ blocklen = LCD_FBWIDTH - blockcount;
+ bitcount = 2 * (count & 3);
+#endif
+
+ if (blockcount)
+ {
+ unsigned char *data = _xlcd_rb->lcd_framebuffer;
+ unsigned char *data_end = data + LCD_FBWIDTH*LCD_HEIGHT;
+
+ do
+ {
+ _xlcd_rb->memmove(data, data + blockcount, blocklen);
+ data += LCD_FBWIDTH;
+ }
+ while (data < data_end);
+ }
+ if (bitcount)
+ {
+ int bx, y;
+ unsigned char *addr = _xlcd_rb->lcd_framebuffer + blocklen;
+#if LCD_DEPTH == 2
+ unsigned fill = 0x55 * (~_xlcd_rb->lcd_get_background() & 3);
+#endif
+
+ for (y = 0; y < LCD_HEIGHT; y++)
+ {
+ unsigned char *row_addr = addr;
+ unsigned data = fill;
+
+ for (bx = 0; bx < blocklen; bx++)
+ {
+ --row_addr;
+ data = (data << 8) | *row_addr;
+ *row_addr = data >> bitcount;
+ }
+ addr += LCD_FBWIDTH;
+ }
+ }
+ oldmode = _xlcd_rb->lcd_get_drawmode();
+ _xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ _xlcd_rb->lcd_fillrect(LCD_WIDTH - count, 0, count, LCD_HEIGHT);
+ _xlcd_rb->lcd_set_drawmode(oldmode);
+}
+
+/* Scroll right */
+void xlcd_scroll_right(int count)
+{
+ int bitcount, oldmode;
+ int blockcount, blocklen;
+
+ if ((unsigned) count >= LCD_WIDTH)
+ return;
+
+#if LCD_DEPTH == 2
+ blockcount = count >> 2;
+ blocklen = LCD_FBWIDTH - blockcount;
+ bitcount = 2 * (count & 3);
+#endif
+
+ if (blockcount)
+ {
+ unsigned char *data = _xlcd_rb->lcd_framebuffer;
+ unsigned char *data_end = data + LCD_FBWIDTH*LCD_HEIGHT;
+
+ do
+ {
+ _xlcd_rb->memmove(data + blockcount, data, blocklen);
+ data += LCD_FBWIDTH;
+ }
+ while (data < data_end);
+ }
+ if (bitcount)
+ {
+ int bx, y;
+ unsigned char *addr = _xlcd_rb->lcd_framebuffer + blockcount;
+#if LCD_DEPTH == 2
+ unsigned fill = 0x55 * (~_xlcd_rb->lcd_get_background() & 3);
+#endif
+
+ for (y = 0; y < LCD_HEIGHT; y++)
+ {
+ unsigned char *row_addr = addr;
+ unsigned data = fill;
+
+ for (bx = 0; bx < blocklen; bx++)
+ {
+ data = (data >> 8) | (*row_addr << bitcount);
+ *row_addr = data;
+ row_addr++;
+ }
+ addr += LCD_FBWIDTH;
+ }
+ }
+ oldmode = _xlcd_rb->lcd_get_drawmode();
+ _xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ _xlcd_rb->lcd_fillrect(0, 0, count, LCD_HEIGHT);
+ _xlcd_rb->lcd_set_drawmode(oldmode);
+}
+
+#else /* LCD_PIXELFORMAT vertical packed or >= 8bit / pixel */
+
+/* Scroll left */
+void xlcd_scroll_left(int count)
+{
+ fb_data *data, *data_end;
+ int length, oldmode;
+
+ if ((unsigned)count >= LCD_WIDTH)
+ 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
+ length = LCD_WIDTH - count;
+
+ do
+ {
+ _xlcd_rb->memmove(data, data + count, length * sizeof(fb_data));
+ data += LCD_WIDTH;
+ }
+ while (data < data_end);
+
+ oldmode = _xlcd_rb->lcd_get_drawmode();
+ _xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ _xlcd_rb->lcd_fillrect(length, 0, count, LCD_HEIGHT);
+ _xlcd_rb->lcd_set_drawmode(oldmode);
+}
+
+/* Scroll right */
+void xlcd_scroll_right(int count)
+{
+ fb_data *data, *data_end;
+ int length, oldmode;
+
+ if ((unsigned)count >= LCD_WIDTH)
+ 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
+ length = LCD_WIDTH - count;
+
+ do
+ {
+ _xlcd_rb->memmove(data + count, data, length * sizeof(fb_data));
+ data += LCD_WIDTH;
+ }
+ while (data < data_end);
+
+ oldmode = _xlcd_rb->lcd_get_drawmode();
+ _xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ _xlcd_rb->lcd_fillrect(0, 0, count, LCD_HEIGHT);
+ _xlcd_rb->lcd_set_drawmode(oldmode);
+}
+
+#endif /* LCD_PIXELFORMAT, LCD_DEPTH */
+
+#if (LCD_PIXELFORMAT == HORIZONTAL_PACKING) || (LCD_DEPTH >= 8)
+
+/* Scroll up */
+void xlcd_scroll_up(int count)
+{
+ int length, oldmode;
+
+ if ((unsigned)count >= LCD_HEIGHT)
+ return;
+
+ length = LCD_HEIGHT - count;
+
+ _xlcd_rb->memmove(_xlcd_rb->lcd_framebuffer,
+ _xlcd_rb->lcd_framebuffer + count * LCD_FBWIDTH,
+ length * LCD_FBWIDTH * sizeof(fb_data));
+
+ oldmode = _xlcd_rb->lcd_get_drawmode();
+ _xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ _xlcd_rb->lcd_fillrect(0, length, LCD_WIDTH, count);
+ _xlcd_rb->lcd_set_drawmode(oldmode);
+}
+
+/* Scroll down */
+void xlcd_scroll_down(int count)
+{
+ int length, oldmode;
+
+ if ((unsigned)count >= LCD_HEIGHT)
+ return;
+
+ length = LCD_HEIGHT - count;
+
+ _xlcd_rb->memmove(_xlcd_rb->lcd_framebuffer + count * LCD_FBWIDTH,
+ _xlcd_rb->lcd_framebuffer,
+ length * LCD_FBWIDTH * sizeof(fb_data));
+
+ oldmode = _xlcd_rb->lcd_get_drawmode();
+ _xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ _xlcd_rb->lcd_fillrect(0, 0, LCD_WIDTH, count);
+ _xlcd_rb->lcd_set_drawmode(oldmode);
+}
+
+#else /* LCD_PIXELFORMAT vertical packed */
+
+/* Scroll up */
+void xlcd_scroll_up(int count)
+{
+ int bitcount, oldmode;
+ int blockcount, blocklen;
+
+ if ((unsigned) count >= LCD_HEIGHT)
+ return;
+
+#if LCD_DEPTH == 1
+ blockcount = count >> 3;
+ blocklen = ((LCD_HEIGHT+7)/8) - blockcount;
+ bitcount = count & 7;
+#elif LCD_DEPTH == 2
+ blockcount = count >> 2;
+ blocklen = ((LCD_HEIGHT+3)/4) - blockcount;
+ bitcount = 2 * (count & 3);
+#endif
+
+ if (blockcount)
+ {
+ _xlcd_rb->memmove(_xlcd_rb->lcd_framebuffer,
+ _xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH,
+ blocklen * LCD_FBWIDTH);
+ }
+ if (bitcount)
+ {
+#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
+ asm (
+ "mov #0,r4 \n" /* x = 0 */
+ "mova .su_shifttbl,r0 \n" /* calculate jump destination for */
+ "mov.b @(r0,%[cnt]),%[cnt] \n" /* shift amount from table */
+ "bra .su_cloop \n" /* skip table */
+ "add r0,%[cnt] \n"
+
+ ".align 2 \n"
+ ".su_shifttbl: \n" /* shift jump offset table */
+ ".byte .su_shift0 - .su_shifttbl \n"
+ ".byte .su_shift1 - .su_shifttbl \n"
+ ".byte .su_shift2 - .su_shifttbl \n"
+ ".byte .su_shift3 - .su_shifttbl \n"
+ ".byte .su_shift4 - .su_shifttbl \n"
+ ".byte .su_shift5 - .su_shifttbl \n"
+ ".byte .su_shift6 - .su_shifttbl \n"
+ ".byte .su_shift7 - .su_shifttbl \n"
+
+ ".su_cloop: \n" /* repeat for every column */
+ "mov %[addr],r2 \n" /* get start address */
+ "mov #0,r3 \n" /* current_row = 0 */
+ "mov #0,r1 \n" /* fill with zero */
+
+ ".su_iloop: \n" /* repeat for all rows */
+ "sub %[wide],r2 \n" /* address -= width */
+ "mov.b @r2,r0 \n" /* get data byte */
+ "shll8 r1 \n" /* old data to 2nd byte */
+ "extu.b r0,r0 \n" /* extend unsigned */
+ "or r1,r0 \n" /* combine old data */
+ "jmp @%[cnt] \n" /* jump into shift "path" */
+ "extu.b r0,r1 \n" /* store data for next round */
+
+ ".su_shift6: \n" /* shift right by 0..7 bits */
+ "shll2 r0 \n"
+ "bra .su_shift0 \n"
+ "shlr8 r0 \n"
+ ".su_shift4: \n"
+ "shlr2 r0 \n"
+ ".su_shift2: \n"
+ "bra .su_shift0 \n"
+ "shlr2 r0 \n"
+ ".su_shift7: \n"
+ "shlr2 r0 \n"
+ ".su_shift5: \n"
+ "shlr2 r0 \n"
+ ".su_shift3: \n"
+ "shlr2 r0 \n"
+ ".su_shift1: \n"
+ "shlr r0 \n"
+ ".su_shift0: \n"
+
+ "mov.b r0,@r2 \n" /* store data */
+ "add #1,r3 \n" /* current_row++ */
+ "cmp/hi r3,%[rows] \n" /* current_row < bheight - shift ? */
+ "bt .su_iloop \n"
+
+ "add #1,%[addr] \n" /* start_address++ */
+ "add #1,r4 \n" /* x++ */
+ "cmp/hi r4,%[wide] \n" /* x < width ? */
+ "bt .su_cloop \n"
+ : /* outputs */
+ : /* inputs */
+ [addr]"r"(_xlcd_rb->lcd_framebuffer + blocklen * LCD_FBWIDTH),
+ [wide]"r"(LCD_FBWIDTH),
+ [rows]"r"(blocklen),
+ [cnt] "r"(bitcount)
+ : /* clobbers */
+ "r0", "r1", "r2", "r3", "r4"
+ );
+#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2)
+ asm (
+ "move.l %[wide],%%d3\n" /* columns = width */
+
+ ".su_cloop: \n" /* repeat for every column */
+ "move.l %[addr],%%a1\n" /* get start address */
+ "move.l %[rows],%%d2\n" /* rows = row_count */
+ "move.l %[bkg],%%d1 \n" /* fill with background */
+
+ ".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,%%d2 \n" /* rows-- */
+ "bne.b .su_iloop \n"
+
+ "addq.l #1,%[addr] \n" /* start_address++ */
+ "subq.l #1,%%d3 \n" /* columns-- */
+ "bne.b .su_cloop \n"
+ : /* outputs */
+ : /* inputs */
+ [wide]"r"(LCD_FBWIDTH),
+ [rows]"r"(blocklen),
+ [addr]"a"(_xlcd_rb->lcd_framebuffer + blocklen * LCD_FBWIDTH),
+ [cnt] "d"(bitcount),
+ [bkg] "d"(0x55 * (~_xlcd_rb->lcd_get_background() & 3))
+ : /* clobbers */
+ "a1", "d0", "d1", "d2", "d3"
+ );
+#else /* C version */
+ int x, by;
+ unsigned char *addr = _xlcd_rb->lcd_framebuffer + blocklen * LCD_FBWIDTH;
+#if LCD_DEPTH == 2
+ unsigned fill = 0x55 * (~_xlcd_rb->lcd_get_background() & 3);
+#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;
+ data = (data << 8) | *col_addr;
+ *col_addr = data >> bitcount;
+ }
+ }
+#endif /* CPU, LCD_DEPTH */
+ }
+ oldmode = _xlcd_rb->lcd_get_drawmode();
+ _xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ _xlcd_rb->lcd_fillrect(0, LCD_HEIGHT - count, LCD_WIDTH, count);
+ _xlcd_rb->lcd_set_drawmode(oldmode);
+}
+
+/* Scroll up */
+void xlcd_scroll_down(int count)
+{
+ int bitcount, oldmode;
+ int blockcount, blocklen;
+
+ if ((unsigned) count >= LCD_HEIGHT)
+ return;
+
+#if LCD_DEPTH == 1
+ blockcount = count >> 3;
+ blocklen = ((LCD_HEIGHT+7)/8) - blockcount;
+ bitcount = count & 7;
+#elif LCD_DEPTH == 2
+ blockcount = count >> 2;
+ blocklen = ((LCD_HEIGHT+3)/4) - blockcount;
+ bitcount = 2 * (count & 3);
+#endif
+
+ if (blockcount)
+ {
+ _xlcd_rb->memmove(_xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH,
+ _xlcd_rb->lcd_framebuffer,
+ blocklen * LCD_FBWIDTH);
+ }
+ if (bitcount)
+ {
+#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
+ asm (
+ "mov #0,r4 \n" /* x = 0 */
+ "mova .sd_shifttbl,r0 \n" /* calculate jump destination for */
+ "mov.b @(r0,%[cnt]),%[cnt] \n" /* shift amount from table */
+ "bra .sd_cloop \n" /* skip table */
+ "add r0,%[cnt] \n"
+
+ ".align 2 \n"
+ ".sd_shifttbl: \n" /* shift jump offset table */
+ ".byte .sd_shift0 - .sd_shifttbl \n"
+ ".byte .sd_shift1 - .sd_shifttbl \n"
+ ".byte .sd_shift2 - .sd_shifttbl \n"
+ ".byte .sd_shift3 - .sd_shifttbl \n"
+ ".byte .sd_shift4 - .sd_shifttbl \n"
+ ".byte .sd_shift5 - .sd_shifttbl \n"
+ ".byte .sd_shift6 - .sd_shifttbl \n"
+ ".byte .sd_shift7 - .sd_shifttbl \n"
+
+ ".sd_cloop: \n" /* repeat for every column */
+ "mov %[addr],r2 \n" /* get start address */
+ "mov #0,r3 \n" /* current_row = 0 */
+ "mov #0,r1 \n" /* fill with zero */
+
+ ".sd_iloop: \n" /* repeat for all rows */
+ "shlr8 r1 \n" /* shift right to get residue */
+ "mov.b @r2,r0 \n" /* get data byte */
+ "jmp @%[cnt] \n" /* jump into shift "path" */
+ "extu.b r0,r0 \n" /* extend unsigned */
+
+ ".sd_shift6: \n" /* shift left by 0..7 bits */
+ "shll8 r0 \n"
+ "bra .sd_shift0 \n"
+ "shlr2 r0 \n"
+ ".sd_shift4: \n"
+ "shll2 r0 \n"
+ ".sd_shift2: \n"
+ "bra .sd_shift0 \n"
+ "shll2 r0 \n"
+ ".sd_shift7: \n"
+ "shll2 r0 \n"
+ ".sd_shift5: \n"
+ "shll2 r0 \n"
+ ".sd_shift3: \n"
+ "shll2 r0 \n"
+ ".sd_shift1: \n"
+ "shll r0 \n"
+ ".sd_shift0: \n"
+
+ "or r0,r1 \n" /* combine with last residue */
+ "mov.b r1,@r2 \n" /* store data */
+ "add %[wide],r2 \n" /* address += width */
+ "add #1,r3 \n" /* current_row++ */
+ "cmp/hi r3,%[rows] \n" /* current_row < bheight - shift ? */
+ "bt .sd_iloop \n"
+
+ "add #1,%[addr] \n" /* start_address++ */
+ "add #1,r4 \n" /* x++ */
+ "cmp/hi r4,%[wide] \n" /* x < width ? */
+ "bt .sd_cloop \n"
+ : /* outputs */
+ : /* inputs */
+ [addr]"r"(_xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH),
+ [wide]"r"(LCD_WIDTH),
+ [rows]"r"(blocklen),
+ [cnt] "r"(bitcount)
+ : /* clobbers */
+ "r0", "r1", "r2", "r3", "r4"
+ );
+#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2)
+ asm (
+ "move.l %[wide],%%d3\n" /* columns = width */
+
+ ".sd_cloop: \n" /* repeat for every column */
+ "move.l %[addr],%%a1\n" /* get start address */
+ "move.l %[rows],%%d2\n" /* rows = row_count */
+ "move.l %[bkg],%%d1 \n" /* fill with background */
+
+ ".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,%%d2 \n" /* rows-- */
+ "bne.b .sd_iloop \n"
+
+ "lea.l (1,%[addr]),%[addr] \n" /* start_address++ */
+ "subq.l #1,%%d3 \n" /* columns-- */
+ "bne.b .sd_cloop \n"
+ : /* outputs */
+ : /* inputs */
+ [wide]"r"(LCD_WIDTH),
+ [rows]"r"(blocklen),
+ [addr]"a"(_xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH),
+ [cnt] "d"(bitcount),
+ [bkg] "d"((0x55 * (~_xlcd_rb->lcd_get_background() & 3)) << bitcount)
+ : /* clobbers */
+ "a1", "d0", "d1", "d2", "d3"
+ );
+#else /* C version */
+ int x, by;
+ unsigned char *addr = _xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH;
+#if LCD_DEPTH == 2
+ unsigned fill = (0x55 * (~_xlcd_rb->lcd_get_background() & 3)) << bitcount;
+#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);
+ *col_addr = data;
+ col_addr += LCD_FBWIDTH;
+ }
+ }
+#endif /* CPU, LCD_DEPTH */
+ }
+ oldmode = _xlcd_rb->lcd_get_drawmode();
+ _xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ _xlcd_rb->lcd_fillrect(0, 0, LCD_WIDTH, count);
+ _xlcd_rb->lcd_set_drawmode(oldmode);
+}
+
+#endif /* LCD_PIXELFORMAT, LCD_DEPTH */
+
+#endif /* HAVE_LCD_BITMAP */
diff --git a/apps/plugins/oscilloscope.c b/apps/plugins/oscilloscope.c
index b69d15daae..de85dc3950 100644
--- a/apps/plugins/oscilloscope.c
+++ b/apps/plugins/oscilloscope.c
@@ -24,6 +24,7 @@
#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
#if CONFIG_CODEC != SWCODEC /* only for MAS-targets */
+#include "xlcd.h"
PLUGIN_HEADER
@@ -77,88 +78,34 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter);
/* implementation */
-void lcd_scroll_left(int count, bool black_border)
-{
- int by;
- unsigned filler;
- unsigned char *ptr;
-
- if ((unsigned) count >= LCD_WIDTH)
- return;
-
- filler = black_border ? 0xFF : 0;
-
- for (by = 0; by < (LCD_HEIGHT/8); by++)
- {
- ptr = rb->lcd_framebuffer + MULU16(LCD_WIDTH, by);
- asm volatile (
- "mov %0,r1 \n" /* check if both source... */
- "or %2,r1 \n" /* ...and offset are even */
- "shlr r1 \n" /* -> lsb = 0 */
- "bf .sl_start2 \n" /* -> copy word-wise */
-
- "add #-1,%2 \n" /* copy byte-wise */
- ".sl_loop1: \n"
- "mov.b @%0+,r1 \n"
- "mov.b r1,@(%2,%0) \n"
- "cmp/hi %0,%1 \n"
- "bt .sl_loop1 \n"
-
- "bra .sl_end \n"
- "nop \n"
-
- ".sl_start2: \n" /* copy word-wise */
- "add #-2,%2 \n"
- ".sl_loop2: \n"
- "mov.w @%0+,r1 \n"
- "mov.w r1,@(%2,%0) \n"
- "cmp/hi %0,%1 \n"
- "bt .sl_loop2 \n"
-
- ".sl_end: \n"
- : /* outputs */
- : /* inputs */
- /* %0 */ "r"(ptr + count),
- /* %1 */ "r"(ptr + LCD_WIDTH),
- /* %2 */ "z"(-count)
- : /* clobbers */
- "r1"
- );
-
- rb->memset(ptr + LCD_WIDTH - count, filler, count);
- }
-}
-
void timer_isr(void)
{
static int last_left, last_right;
bool full_update = false;
if (new_val)
- {
+ {
if ((unsigned)x >= LCD_WIDTH)
{
if (scroll)
{
- lcd_scroll_left(1, false);
+ xlcd_scroll_left(1);
x = LCD_WIDTH-1;
full_update = true;
}
else
x = 0;
}
-
+
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- rb->lcd_drawline(x, 0, x, LCD_HEIGHT-1);
+ rb->lcd_vline(x, 0, LCD_HEIGHT-1);
rb->lcd_set_drawmode(DRMODE_SOLID);
switch (draw_mode)
{
case DRAW_MODE_FILLED:
- rb->lcd_drawline(x, LCD_HEIGHT/2+1,
- x, LCD_HEIGHT/2+1 + left_val);
- rb->lcd_drawline(x, LCD_HEIGHT/2-1,
- x, LCD_HEIGHT/2-1 - right_val);
+ rb->lcd_vline(x, LCD_HEIGHT/2+1, LCD_HEIGHT/2+1 + left_val);
+ rb->lcd_vline(x, LCD_HEIGHT/2-1, LCD_HEIGHT/2-1 - right_val);
break;
case DRAW_MODE_OUTLINE:
@@ -205,6 +152,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
(void)parameter;
rb = api;
+
+ xlcd_init(rb);
rb->timer_register(1, NULL, FREQ / 67, 1, timer_isr);
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c
index 164e94cb73..a76ebe1f0d 100644
--- a/firmware/drivers/lcd-2bit-horz.c
+++ b/firmware/drivers/lcd-2bit-horz.c
@@ -38,7 +38,7 @@
/*** globals ***/
-unsigned char lcd_framebuffer[LCD_HEIGHT][FB_WIDTH] IBSS_ATTR;
+unsigned char lcd_framebuffer[LCD_HEIGHT][LCD_FBWIDTH] IBSS_ATTR;
static const unsigned char dibits[16] ICONST_ATTR = {
0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F,
@@ -419,11 +419,11 @@ void lcd_vline(int x, int y1, int y2)
dst = &lcd_framebuffer[y1][x>>2];
mask = pixmask[x & 3];
- dst_end = dst + (y2 - y1) * FB_WIDTH;
+ dst_end = dst + (y2 - y1) * LCD_FBWIDTH;
do
{
bfunc(dst, mask, 0xFFu);
- dst += FB_WIDTH;
+ dst += LCD_FBWIDTH;
}
while (dst <= dst_end);
}
@@ -482,11 +482,11 @@ void lcd_fillrect(int x, int y, int width, int height)
{
unsigned char *dst_col = dst;
- dst_end = dst_col + height * FB_WIDTH;
+ dst_end = dst_col + height * LCD_FBWIDTH;
do
{
bfunc(dst_col, mask, 0xFFu);
- dst_col += FB_WIDTH;
+ dst_col += LCD_FBWIDTH;
}
while (dst_col < dst_end);
@@ -495,11 +495,11 @@ void lcd_fillrect(int x, int y, int width, int height)
}
mask &= mask_right;
- dst_end = dst + height * FB_WIDTH;
+ dst_end = dst + height * LCD_FBWIDTH;
do
{
bfunc(dst, mask, 0xFFu);
- dst += FB_WIDTH;
+ dst += LCD_FBWIDTH;
}
while (dst < dst_end);
}
@@ -651,7 +651,7 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
mask_right = 0xFFu >> (2 * (~nx & 3));
shift *= 2;
- dst_end = dst + height * FB_WIDTH;
+ dst_end = dst + height * LCD_FBWIDTH;
do
{
const unsigned char *src_row = src;
@@ -678,7 +678,7 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
setblock(dst_row, mask_row & mask_right, data);
src += stride;
- dst += FB_WIDTH;
+ dst += LCD_FBWIDTH;
}
while (dst < dst_end);
}
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 6f7fef94ee..89bf35300c 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -205,8 +205,8 @@ typedef void lcd_fastpixelfunc_type(fb_data *address);
extern fb_data lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH];
#elif LCD_DEPTH == 2
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
-#define FB_WIDTH ((LCD_WIDTH+3)/4)
-extern fb_data lcd_framebuffer[LCD_HEIGHT][FB_WIDTH];
+#define LCD_FBWIDTH ((LCD_WIDTH+3)/4)
+extern fb_data lcd_framebuffer[LCD_HEIGHT][LCD_FBWIDTH];
#else
extern fb_data lcd_framebuffer[LCD_HEIGHT/4][LCD_WIDTH];
#endif
@@ -214,6 +214,10 @@ extern fb_data lcd_framebuffer[LCD_HEIGHT/4][LCD_WIDTH];
extern fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH];
#elif LCD_DEPTH == 18
extern fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH];
+#endif
+
+#ifndef LCD_FBWIDTH
+#define LCD_FBWIDTH LCD_WIDTH
#endif
#if (CONFIG_BACKLIGHT==BL_IRIVER_H300) || (CONFIG_BACKLIGHT==BL_IPOD3G)