summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-09-23 11:17:52 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-09-23 11:17:52 +0000
commit86f9a8410b8cfe53b11ca10f4f6dbcc2440c0e97 (patch)
tree48a2555b17b1b485b9c5f8c1385296f6cdff2309 /firmware/drivers
parente0d60436b2ab01d02e577b2f4cd9c8967d74d635 (diff)
Split lcd driver into lcd-player and lcd-recorder. Player simulator still needs fixing.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2370 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/lcd-player.c348
-rw-r--r--firmware/drivers/lcd-recorder.c766
-rw-r--r--firmware/drivers/lcd.c1090
-rw-r--r--firmware/drivers/lcd.h1
4 files changed, 1119 insertions, 1086 deletions
diff --git a/firmware/drivers/lcd-player.c b/firmware/drivers/lcd-player.c
new file mode 100644
index 0000000000..f2a034f8da
--- /dev/null
+++ b/firmware/drivers/lcd-player.c
@@ -0,0 +1,348 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Alan Korr
+ *
+ * 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 "config.h"
+
+#ifdef HAVE_LCD_CHARCELLS
+
+#include "lcd.h"
+#include "kernel.h"
+#include "thread.h"
+#include <string.h>
+#include <stdlib.h>
+#include "file.h"
+#include "debug.h"
+#include "system.h"
+#include "font.h"
+
+#if defined(SIMULATOR)
+#include "sim_icons.h"
+#endif
+
+/*** definitions ***/
+
+#ifdef HAVE_NEW_CHARCELL_LCD
+# define LCD_CONTRAST_SET ((char)0x50)
+# define LCD_CRAM ((char)0x80) /* Characters */
+# define LCD_PRAM ((char)0xC0) /* Patterns */
+# define LCD_IRAM ((char)0x40) /* Icons */
+#else
+# define LCD_CONTRAST_SET ((char)0xA8)
+# define LCD_CRAM ((char)0xB0) /* Characters */
+# define LCD_PRAM ((char)0x80) /* Patterns */
+# define LCD_IRAM ((char)0xE0) /* Icons */
+#endif
+#define LCD_CURSOR(x,y) ((char)(LCD_CRAM+((y)*16+(x))))
+#define LCD_ICON(i) ((char)(LCD_IRAM+i))
+
+/*** generic code ***/
+
+struct scrollinfo {
+ char text[MAX_PATH];
+ char line[32];
+ int textlen;
+ int offset;
+ int startx;
+ int starty;
+ int space;
+};
+
+static void scroll_thread(void);
+static char scroll_stack[DEFAULT_STACK_SIZE];
+static char scroll_name[] = "scroll";
+static char scroll_speed = 8; /* updates per second */
+static char scroll_spacing = 3; /* spaces between end and start of text */
+
+
+static struct scrollinfo scroll; /* only one scroll line at the moment */
+static int scroll_count = 0;
+
+#ifdef HAVE_NEW_CHARCELL_LCD
+
+static const unsigned char lcd_ascii[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x05,0x13,0x14,0x15,0x16,0x17,
+ 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
+ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
+ 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
+ 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
+ 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
+ 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
+ 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
+ 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
+ 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
+ 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
+ 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
+ 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
+ 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
+ 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,
+ 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
+ 0x41,0x41,0x41,0x41,0x41,0x41,0x20,0x43,
+ 0x45,0x45,0x45,0x45,0x49,0x49,0x49,0x49,
+ 0x44,0x4e,0x4f,0x4f,0x4f,0x4f,0x4f,0x20,
+ 0x20,0x55,0x55,0x55,0x55,0x59,0x20,0x20,
+ 0x61,0x61,0x61,0x61,0x61,0x61,0x20,0x63,
+ 0x65,0x65,0x65,0x65,0x69,0x69,0x69,0x69,
+ 0x6f,0x6e,0x6f,0x6f,0x6f,0x6f,0x6f,0x20,
+ 0x20,0x75,0x75,0x75,0x75,0x79,0x20,0x79
+};
+
+#else
+
+static const unsigned char lcd_ascii[] = {
+ 0x00,0x01,0x02,0x03,0x00,0x84,0x85,0x89,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xec,0xe3,0xe2,0xe1,0xe0,0xdf,0x15,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x24,0x25,0x26,0x37,0x06,0x29,0x2a,0x2b,
+ 0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,
+ 0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,
+ 0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,
+ 0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,
+ 0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,
+ 0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,
+ 0x5c,0x5d,0x5e,0xa9,0x33,0xce,0x00,0x15,
+ 0x00,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
+ 0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
+ 0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,
+ 0x7c,0x7d,0x7e,0x24,0x24,0x24,0x24,0x24,
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
+ 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
+ 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
+ 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
+ 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,
+ 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
+ 0x45,0x45,0x45,0x45,0x45,0x45,0x24,0x47,
+ 0x49,0x49,0x49,0x49,0x4d,0x4d,0x4d,0x4d,
+ 0x48,0x52,0x53,0x53,0x53,0x53,0x53,0x24,
+ 0x24,0x59,0x59,0x59,0x59,0x5d,0x24,0x24,
+ 0x65,0x65,0x65,0x65,0x65,0x65,0x24,0x67,
+ 0x69,0x69,0x69,0x69,0x6d,0x6d,0x6d,0x6d,
+ 0x73,0x72,0x73,0x73,0x73,0x73,0x73,0x24,
+ 0x24,0x79,0x79,0x79,0x79,0x7d,0x24,0x7d
+};
+#endif /* HAVE_NEW_CHARCELL_LCD */
+
+void lcd_clear_display(void)
+{
+ int i;
+ lcd_write(true,LCD_CURSOR(0,0));
+ for (i=0;i<32;i++)
+ lcd_write(false,lcd_ascii[' ']);
+}
+
+void lcd_puts(int x, int y, unsigned char *string)
+{
+ int i;
+ lcd_write(true,LCD_CURSOR(x,y));
+ for (i=0; *string && x++<11; i++)
+ lcd_write(false,lcd_ascii[*(unsigned char*)string++]);
+ for (; x<11; x++)
+ lcd_write(false,lcd_ascii[' ']);
+}
+
+void lcd_putc(int x, int y, unsigned char ch)
+{
+ lcd_write(true,LCD_CURSOR(x,y));
+ lcd_write(false,lcd_ascii[ch]);
+}
+
+void lcd_define_pattern (int which,char *pattern,int length)
+{
+ int i;
+ lcd_write(true,LCD_PRAM|which);
+ for (i=0;i<length;i++)
+ lcd_write(false,pattern[i]);
+}
+
+void lcd_double_height(bool on)
+{
+ lcd_write(true,on?9:8);
+}
+
+static char icon_pos[] =
+{
+ 0, 0, 0, 0, /* Battery */
+ 2, /* USB */
+ 3, /* Play */
+ 4, /* Record */
+ 5, /* Pause */
+ 5, /* Audio */
+ 6, /* Repeat */
+ 7, /* 1 */
+ 9, /* Volume */
+ 9, /* Volume 1 */
+ 9, /* Volume 2 */
+ 10, /* Volume 3 */
+ 10, /* Volume 4 */
+ 10, /* Volume 5 */
+ 10, /* Param */
+};
+
+static char icon_mask[] =
+{
+ 0x02, 0x08, 0x04, 0x10, /* Battery */
+ 0x04, /* USB */
+ 0x10, /* Play */
+ 0x10, /* Record */
+ 0x02, /* Pause */
+ 0x10, /* Audio */
+ 0x02, /* Repeat */
+ 0x01, /* 1 */
+ 0x04, /* Volume */
+ 0x02, /* Volume 1 */
+ 0x01, /* Volume 2 */
+ 0x08, /* Volume 3 */
+ 0x04, /* Volume 4 */
+ 0x01, /* Volume 5 */
+ 0x10, /* Param */
+};
+
+void lcd_icon(int icon, bool enable)
+{
+ static unsigned char icon_mirror[11] = {0};
+ int pos, mask;
+
+ pos = icon_pos[icon];
+ mask = icon_mask[icon];
+
+ lcd_write(true, LCD_ICON(pos));
+
+ if(enable)
+ icon_mirror[pos] |= mask;
+ else
+ icon_mirror[pos] &= ~mask;
+
+ lcd_write(false, icon_mirror[pos]);
+}
+
+void lcd_init (void)
+{
+ create_thread(scroll_thread, scroll_stack,
+ sizeof(scroll_stack), scroll_name);
+}
+
+void lcd_set_contrast(int val)
+{
+ lcd_write(true, LCD_CONTRAST_SET);
+ lcd_write(false, 31-val);
+}
+
+void lcd_puts_scroll(int x, int y, unsigned char* string )
+{
+ struct scrollinfo* s = &scroll;
+ s->space = 11 - x;
+
+ lcd_puts(x,y,string);
+ s->textlen = strlen(string);
+
+ if ( s->textlen > s->space ) {
+ s->offset=s->space;
+ s->startx=x;
+ s->starty=y;
+ strncpy(s->text,string,sizeof s->text);
+ s->text[sizeof s->text - 1] = 0;
+ memset(s->line, 0, sizeof s->line);
+ strncpy(s->line,string,
+ s->space > (int)sizeof s->line ?
+ (int)sizeof s->line : s->space );
+ s->line[sizeof s->line - 1] = 0;
+ scroll_count = 1;
+ }
+}
+
+
+void lcd_stop_scroll(void)
+{
+ if ( scroll_count ) {
+ struct scrollinfo* s = &scroll;
+ scroll_count = 0;
+
+ /* restore scrolled row */
+ lcd_puts(s->startx,s->starty,s->text);
+ lcd_update();
+ }
+}
+
+void lcd_scroll_pause(void)
+{
+ scroll_count = 0;
+}
+
+void lcd_scroll_resume(void)
+{
+ scroll_count = 1;
+}
+
+void lcd_scroll_speed(int speed)
+{
+ scroll_speed = speed;
+}
+
+static void scroll_thread(void)
+{
+ struct scrollinfo* s = &scroll;
+
+ while ( 1 ) {
+ if ( !scroll_count ) {
+ yield();
+ continue;
+ }
+ /* wait 0.5s before starting scroll */
+ if ( scroll_count < scroll_speed/2 )
+ scroll_count++;
+ else {
+ int i;
+ for ( i=0; i<s->space-1; i++ )
+ s->line[i] = s->line[i+1];
+
+ if ( s->offset < s->textlen ) {
+ s->line[(int)s->space - 1] = s->text[(int)s->offset];
+ s->offset++;
+ }
+ else {
+ s->line[s->space - 1] = ' ';
+ if ( s->offset < s->textlen + scroll_spacing - 1 )
+ s->offset++;
+ else
+ s->offset = 0;
+ }
+
+ lcd_puts(s->startx,s->starty,s->line);
+ lcd_update();
+ }
+ sleep(HZ/scroll_speed);
+ }
+}
+
+#endif /* HAVE_LCD_CHARCELLS */
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../rockbox-mode.el")
+ * end:
+ */
diff --git a/firmware/drivers/lcd-recorder.c b/firmware/drivers/lcd-recorder.c
new file mode 100644
index 0000000000..9f19bb89f0
--- /dev/null
+++ b/firmware/drivers/lcd-recorder.c
@@ -0,0 +1,766 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Alan Korr
+ *
+ * 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 "config.h"
+
+#ifdef HAVE_LCD_BITMAP
+
+#include "lcd.h"
+#include "kernel.h"
+#include "thread.h"
+#include <string.h>
+#include <stdlib.h>
+#include "file.h"
+#include "debug.h"
+#include "system.h"
+#include "font.h"
+
+/*** definitions ***/
+
+#define LCD_SET_LOWER_COLUMN_ADDRESS ((char)0x00)
+#define LCD_SET_HIGHER_COLUMN_ADDRESS ((char)0x10)
+#define LCD_SET_INTERNAL_REGULATOR_RESISTOR_RATIO ((char)0x20)
+#define LCD_SET_POWER_CONTROL_REGISTER ((char)0x28)
+#define LCD_SET_DISPLAY_START_LINE ((char)0x40)
+#define LCD_SET_CONTRAST_CONTROL_REGISTER ((char)0x81)
+#define LCD_SET_SEGMENT_REMAP ((char)0xA0)
+#define LCD_SET_LCD_BIAS ((char)0xA2)
+#define LCD_SET_ENTIRE_DISPLAY_OFF ((char)0xA4)
+#define LCD_SET_ENTIRE_DISPLAY_ON ((char)0xA5)
+#define LCD_SET_NORMAL_DISPLAY ((char)0xA6)
+#define LCD_SET_REVERSE_DISPLAY ((char)0xA7)
+#define LCD_SET_INDICATOR_OFF ((char)0xAC)
+#define LCD_SET_INDICATOR_ON ((char)0xAD)
+#define LCD_SET_DISPLAY_OFF ((char)0xAE)
+#define LCD_SET_DISPLAY_ON ((char)0xAF)
+#define LCD_SET_PAGE_ADDRESS ((char)0xB0)
+#define LCD_SET_COM_OUTPUT_SCAN_DIRECTION ((char)0xC0)
+#define LCD_SET_DISPLAY_OFFSET ((char)0xD3)
+#define LCD_SET_READ_MODIFY_WRITE_MODE ((char)0xE0)
+#define LCD_SOFTWARE_RESET ((char)0xE2)
+#define LCD_NOP ((char)0xE3)
+#define LCD_SET_END_OF_READ_MODIFY_WRITE_MODE ((char)0xEE)
+
+/* LCD command codes */
+#define LCD_CNTL_RESET 0xe2 // Software reset
+#define LCD_CNTL_POWER 0x2f // Power control
+#define LCD_CNTL_CONTRAST 0x81 // Contrast
+#define LCD_CNTL_OUTSCAN 0xc8 // Output scan direction
+#define LCD_CNTL_SEGREMAP 0xa1 // Segment remap
+#define LCD_CNTL_DISPON 0xaf // Display on
+
+#define LCD_CNTL_PAGE 0xb0 // Page address
+#define LCD_CNTL_HIGHCOL 0x10 // Upper column address
+#define LCD_CNTL_LOWCOL 0x00 // Lower column address
+
+struct scrollinfo {
+ char text[MAX_PATH];
+ char line[32];
+ int textlen;
+ int offset;
+ int startx;
+ int starty;
+ int space;
+};
+
+static void scroll_thread(void);
+static char scroll_stack[DEFAULT_STACK_SIZE];
+static char scroll_name[] = "scroll";
+static char scroll_speed = 8; /* updates per second */
+static char scroll_spacing = 3; /* spaces between end and start of text */
+static struct scrollinfo scroll; /* only one scroll line at the moment */
+static int scroll_count = 0;
+static int xmargin = 0;
+static int ymargin = 0;
+static int curfont = FONT_SYSFIXED;
+
+#ifdef SIMULATOR
+unsigned char lcd_framebuffer[LCD_WIDTH][LCD_HEIGHT/8];
+#else
+static unsigned char lcd_framebuffer[LCD_WIDTH][LCD_HEIGHT/8];
+#endif
+
+/* All zeros and ones bitmaps for area filling */
+static unsigned char zeros[8] = { 0 };
+static unsigned char ones[8] = { 0xff };
+
+#ifdef SIMULATOR
+
+void lcd_init(void)
+{
+ create_thread(scroll_thread, scroll_stack,
+ sizeof(scroll_stack), scroll_name);
+}
+
+#else
+
+/*
+ * Initialize LCD
+ */
+void lcd_init (void)
+{
+ /* Initialize PB0-3 as output pins */
+ PBCR2 &= 0xff00; /* MD = 00 */
+ PBIOR |= 0x000f; /* IOR = 1 */
+
+ lcd_clear_display();
+ lcd_update();
+ create_thread(scroll_thread, scroll_stack,
+ sizeof(scroll_stack), scroll_name);
+}
+
+/*
+ * Update the display.
+ * This must be called after all other LCD functions that change the display.
+ */
+void lcd_update (void) __attribute__ ((section (".icode")));
+void lcd_update (void)
+{
+ int x, y;
+
+ /* Copy display bitmap to hardware */
+ for (y = 0; y < LCD_HEIGHT/8; y++)
+ {
+ lcd_write (true, LCD_CNTL_PAGE | (y & 0xf));
+ lcd_write (true, LCD_CNTL_HIGHCOL);
+ lcd_write (true, LCD_CNTL_LOWCOL);
+
+ for (x = 0; x < LCD_WIDTH; x++)
+ lcd_write (false, lcd_framebuffer[x][y]);
+ }
+}
+
+/*
+ * Update a fraction of the display.
+ */
+void lcd_update_rect (int, int, int, int) __attribute__ ((section (".icode")));
+void lcd_update_rect (int x_start, int y,
+ int width, int height)
+{
+ int ymax;
+ int xmax;
+ int x;
+
+ /* The Y coordinates have to work on even 8 pixel rows */
+ ymax = (y + height)/8;
+ y /= 8;
+
+ xmax = x_start + width;
+
+ if(xmax > LCD_WIDTH)
+ xmax = LCD_WIDTH;
+ if(ymax >= LCD_HEIGHT/8)
+ ymax = LCD_HEIGHT/8-1;
+
+ /* Copy specified rectange bitmap to hardware */
+ for (; y <= ymax; y++)
+ {
+ lcd_write (true, LCD_CNTL_PAGE | (y & 0xf));
+ lcd_write (true, LCD_CNTL_HIGHCOL | ((x_start>>4) & 0xf));
+ lcd_write (true, LCD_CNTL_LOWCOL | (x_start & 0xf));
+
+ for (x = x_start; x < xmax; x++)
+ lcd_write (false, lcd_framebuffer[x][y]);
+ }
+}
+
+void lcd_set_contrast(int val)
+{
+ lcd_write(true, LCD_CNTL_CONTRAST);
+ lcd_write(true, val);
+}
+
+/**
+ * Rolls up the lcd display by the specified amount of lines.
+ * Lines that are rolled out over the top of the screen are
+ * rolled in from the bottom again. This is a hardware
+ * remapping only and all operations on the lcd are affected.
+ * ->
+ * @param int lines - The number of lines that are rolled.
+ * The value must be 0 <= pixels < LCD_HEIGHT.
+ */
+void lcd_roll(int lines)
+{
+ lcd_write(true, LCD_SET_DISPLAY_START_LINE | (lines & (LCD_HEIGHT-1)));
+}
+
+#endif /* SIMULATOR */
+
+void lcd_clear_display (void)
+{
+ memset (lcd_framebuffer, 0, sizeof lcd_framebuffer);
+}
+
+void lcd_setmargins(int x, int y)
+{
+ xmargin = x;
+ ymargin = y;
+}
+
+int lcd_getxmargin(void)
+{
+ return xmargin;
+}
+
+int lcd_getymargin(void)
+{
+ return ymargin;
+}
+
+void lcd_setfont(int newfont)
+{
+ curfont = newfont;
+}
+
+void lcd_getfontsize(int font, int *width, int *height)
+{
+ struct font* pf = font_get(font);
+
+ *width = pf->maxwidth;
+ *height = pf->height;
+}
+
+int lcd_getstringsize(unsigned char *str, int font, int *w, int *h)
+{
+ struct font* pf = font_get(font);
+ int ch;
+ int width = 0;
+
+ while((ch = *str++)) {
+ /* check input range*/
+ if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
+ ch = pf->defaultchar;
+ ch -= pf->firstchar;
+
+ /* get proportional width and glyph bits*/
+ width += pf->width? pf->width[ch]: pf->maxwidth;
+ }
+ *w = width;
+ *h = pf->height;
+
+ return width;
+}
+
+/* put a string at a given char position */
+void lcd_puts(int x, int y, unsigned char *str)
+{
+ int xpos,ypos,w,h;
+
+#if defined(SIMULATOR) && defined(HAVE_LCD_CHARCELLS)
+ /* We make the simulator truncate the string if it reaches the right edge,
+ as otherwise it'll wrap. The real target doesn't wrap. */
+
+ char buffer[12];
+ if(strlen(str)+x > 11 ) {
+ strncpy(buffer, str, sizeof buffer);
+ buffer[11-x]=0;
+ str = buffer;
+ }
+ xmargin = 0;
+ ymargin = 8;
+#endif
+
+ if(!str || !str[0])
+ return;
+
+ lcd_getstringsize(str, curfont, &w, &h);
+ xpos = xmargin + x*w / strlen(str);
+ ypos = ymargin + y*h;
+ lcd_putsxy( xpos, ypos, str, curfont);
+ lcd_clearrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h);
+
+#if defined(SIMULATOR) && defined(HAVE_LCD_CHARCELLS)
+ /* this function is being used when simulating a charcell LCD and
+ then we update immediately */
+ lcd_update();
+#endif
+}
+
+/* put a string at a given pixel position */
+void lcd_putsxy(int x, int y, unsigned char *str, int font)
+{
+ int ch;
+ struct font* pf = font_get(font);
+
+ while (((ch = *str++) != '\0')) {
+ bitmap_t *bits;
+ int width;
+
+ /* check input range*/
+ if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
+ ch = pf->defaultchar;
+ ch -= pf->firstchar;
+
+ /* get proportional width and glyph bits*/
+ width = pf->width ? pf->width[ch] : pf->maxwidth;
+ if (x + width > LCD_WIDTH)
+ break;
+
+ /* no partial-height drawing for now...*/
+ if (y + pf->height > LCD_HEIGHT)
+ break;
+ bits = pf->bits + (pf->offset ? pf->offset[ch] : (pf->height * ch));
+
+ lcd_bitmap((unsigned char *)bits, x, y, width, pf->height, true);
+ x += width;
+ }
+}
+
+/*
+ * All bitmaps have this format:
+ * Bits within a byte are arranged veritcally, LSB at top.
+ * Bytes are stored in column-major format, with byte 0 at top left,
+ * byte 1 is 2nd from top, etc. Bytes following left-most column
+ * starts 2nd left column, etc.
+ *
+ * Note: The HW takes bitmap bytes in row-major order.
+ *
+ * Memory copy of display bitmap
+ */
+
+/*
+ * Draw a bitmap at (x, y), size (nx, ny)
+ * if 'clear' is true, clear destination area first
+ */
+void lcd_bitmap (unsigned char *src, int x, int y, int nx, int ny,
+ bool clear) __attribute__ ((section (".icode")));
+void lcd_bitmap (unsigned char *src, int x, int y, int nx, int ny,
+ bool clear)
+{
+ unsigned char *dst;
+ unsigned char *dst2;
+ unsigned int data, mask, mask2, mask3, mask4;
+ int shift;
+
+ if (((unsigned)x >= LCD_WIDTH) || ((unsigned)y >= LCD_HEIGHT))
+ return;
+ if (((unsigned)(x + nx)) >= LCD_WIDTH)
+ nx = LCD_WIDTH - x;
+ if (((unsigned)(y + ny)) >= LCD_HEIGHT)
+ ny = LCD_HEIGHT - y;
+
+ shift = y & 7;
+ dst2 = &lcd_framebuffer[x][y/8];
+ ny += shift;
+
+ /* Calculate bit masks */
+ mask4 = ~(0xfe << ((ny-1) & 7));
+ if (clear)
+ {
+ mask = ~(0xff << shift);
+ mask2 = 0;
+ mask3 = ~mask4;
+ if (ny <= 8)
+ mask3 |= mask;
+ }
+ else
+ mask = mask2 = mask3 = 0xff;
+
+ /* Loop for each column */
+ for (x = 0; x < nx; x++)
+ {
+ dst = dst2;
+ dst2 += LCD_HEIGHT/8;
+ data = 0;
+ y = 0;
+
+ if (ny > 8)
+ {
+ /* First partial row */
+ data = *src++ << shift;
+ *dst = (*dst & mask) | data;
+ data >>= 8;
+ dst++;
+
+ /* Intermediate rows */
+ for (y = 8; y < ny-8; y += 8)
+ {
+ data |= *src++ << shift;
+ *dst = (*dst & mask2) | data;
+ data >>= 8;
+ dst++;
+ }
+ }
+
+ /* Last partial row */
+ if (y + shift < ny)
+ data |= *src++ << shift;
+ *dst = (*dst & mask3) | (data & mask4);
+ }
+}
+
+/*
+ * Draw a rectangle with upper left corner at (x, y)
+ * and size (nx, ny)
+ */
+void lcd_drawrect (int x, int y, int nx, int ny)
+{
+ int i;
+
+ if (x > LCD_WIDTH)
+ return;
+ if (y > LCD_HEIGHT)
+ return;
+
+ if (x + nx > LCD_WIDTH)
+ nx = LCD_WIDTH - x;
+ if (y + ny > LCD_HEIGHT)
+ ny = LCD_HEIGHT - y;
+
+ /* vertical lines */
+ for (i = 0; i < ny; i++) {
+ DRAW_PIXEL(x, (y + i));
+ DRAW_PIXEL((x + nx - 1), (y + i));
+ }
+
+ /* horizontal lines */
+ for (i = 0; i < nx; i++) {
+ DRAW_PIXEL((x + i),y);
+ DRAW_PIXEL((x + i),(y + ny - 1));
+ }
+}
+
+/*
+ * Clear a rectangular area at (x, y), size (nx, ny)
+ */
+void lcd_clearrect (int x, int y, int nx, int ny)
+{
+ int i;
+ for (i = 0; i < nx; i++)
+ lcd_bitmap (zeros, x+i, y, 1, ny, true);
+}
+
+/*
+ * Fill a rectangular area at (x, y), size (nx, ny)
+ */
+void lcd_fillrect (int x, int y, int nx, int ny)
+{
+ int i;
+ for (i = 0; i < nx; i++)
+ lcd_bitmap (ones, x+i, y, 1, ny, true);
+}
+
+/* Invert a rectangular area at (x, y), size (nx, ny) */
+void lcd_invertrect (int x, int y, int nx, int ny)
+{
+ int i, j;
+
+ if (x > LCD_WIDTH)
+ return;
+ if (y > LCD_HEIGHT)
+ return;
+
+ if (x + nx > LCD_WIDTH)
+ nx = LCD_WIDTH - x;
+ if (y + ny > LCD_HEIGHT)
+ ny = LCD_HEIGHT - y;
+
+ for (i = 0; i < nx; i++)
+ for (j = 0; j < ny; j++)
+ INVERT_PIXEL((x + i), (y + j));
+}
+
+void lcd_drawline( int x1, int y1, int x2, int y2 )
+{
+ int numpixels;
+ int i;
+ int deltax, deltay;
+ int d, dinc1, dinc2;
+ int x, xinc1, xinc2;
+ int y, yinc1, yinc2;
+
+ deltax = abs(x2 - x1);
+ deltay = abs(y2 - y1);
+
+ if(deltax >= deltay)
+ {
+ numpixels = deltax;
+ d = 2 * deltay - deltax;
+ dinc1 = deltay * 2;
+ dinc2 = (deltay - deltax) * 2;
+ xinc1 = 1;
+ xinc2 = 1;
+ yinc1 = 0;
+ yinc2 = 1;
+ }
+ else
+ {
+ numpixels = deltay;
+ d = 2 * deltax - deltay;
+ dinc1 = deltax * 2;
+ dinc2 = (deltax - deltay) * 2;
+ xinc1 = 0;
+ xinc2 = 1;
+ yinc1 = 1;
+ yinc2 = 1;
+ }
+ numpixels++; /* include endpoints */
+
+ if(x1 > x2)
+ {
+ xinc1 = -xinc1;
+ xinc2 = -xinc2;
+ }
+
+ if(y1 > y2)
+ {
+ yinc1 = -yinc1;
+ yinc2 = -yinc2;
+ }
+
+ x = x1;
+ y = y1;
+
+ for(i=0; i<numpixels; i++)
+ {
+ DRAW_PIXEL(x,y);
+
+ if(d < 0)
+ {
+ d += dinc1;
+ x += xinc1;
+ y += yinc1;
+ }
+ else
+ {
+ d += dinc2;
+ x += xinc2;
+ y += yinc2;
+ }
+ }
+}
+
+void lcd_clearline( int x1, int y1, int x2, int y2 )
+{
+ int numpixels;
+ int i;
+ int deltax, deltay;
+ int d, dinc1, dinc2;
+ int x, xinc1, xinc2;
+ int y, yinc1, yinc2;
+
+ deltax = abs(x2 - x1);
+ deltay = abs(y2 - y1);
+
+ if(deltax >= deltay)
+ {
+ numpixels = deltax;
+ d = 2 * deltay - deltax;
+ dinc1 = deltay * 2;
+ dinc2 = (deltay - deltax) * 2;
+ xinc1 = 1;
+ xinc2 = 1;
+ yinc1 = 0;
+ yinc2 = 1;
+ }
+ else
+ {
+ numpixels = deltay;
+ d = 2 * deltax - deltay;
+ dinc1 = deltax * 2;
+ dinc2 = (deltax - deltay) * 2;
+ xinc1 = 0;
+ xinc2 = 1;
+ yinc1 = 1;
+ yinc2 = 1;
+ }
+ numpixels++; /* include endpoints */
+
+ if(x1 > x2)
+ {
+ xinc1 = -xinc1;
+ xinc2 = -xinc2;
+ }
+
+ if(y1 > y2)
+ {
+ yinc1 = -yinc1;
+ yinc2 = -yinc2;
+ }
+
+ x = x1;
+ y = y1;
+
+ for(i=0; i<numpixels; i++)
+ {
+ CLEAR_PIXEL(x,y);
+
+ if(d < 0)
+ {
+ d += dinc1;
+ x += xinc1;
+ y += yinc1;
+ }
+ else
+ {
+ d += dinc2;
+ x += xinc2;
+ y += yinc2;
+ }
+ }
+}
+
+/*
+ * Set a single pixel
+ */
+void lcd_drawpixel(int x, int y)
+{
+ DRAW_PIXEL(x,y);
+}
+
+/*
+ * Clear a single pixel
+ */
+void lcd_clearpixel(int x, int y)
+{
+ CLEAR_PIXEL(x,y);
+}
+
+/*
+ * Invert a single pixel
+ */
+void lcd_invertpixel(int x, int y)
+{
+ INVERT_PIXEL(x,y);
+}
+
+void lcd_puts_scroll(int x, int y, unsigned char* string )
+{
+ struct scrollinfo* s = &scroll;
+ unsigned char ch[2];
+ int w, h;
+ int width, height;
+ lcd_getfontsize(curfont, &width, &height);
+
+ ch[1] = 0; /* zero terminate */
+ ch[0] = string[0];
+ width = 0;
+ s->space = 0;
+ while ( ch[0] &&
+ (width + lcd_getstringsize(ch, curfont, &w, &h) <
+ (LCD_WIDTH - x*8))) {
+ width += w;
+ s->space++;
+ ch[0]=string[s->space];
+ }
+
+ lcd_puts(x,y,string);
+ s->textlen = strlen(string);
+
+ s->space += 2;
+ lcd_getstringsize(string,curfont,&w,&h);
+ if ( w > LCD_WIDTH - xmargin ) {
+ s->offset=s->space;
+ s->startx=x;
+ s->starty=y;
+ strncpy(s->text,string,sizeof s->text);
+ s->text[sizeof s->text - 1] = 0;
+ memset(s->line, 0, sizeof s->line);
+ strncpy(s->line,string,
+ s->space > (int)sizeof s->line ?
+ (int)sizeof s->line : s->space );
+ s->line[sizeof s->line - 1] = 0;
+ scroll_count = 1;
+ }
+}
+
+
+void lcd_stop_scroll(void)
+{
+ if ( scroll_count ) {
+ int w,h;
+ struct scrollinfo* s = &scroll;
+ scroll_count = 0;
+
+ lcd_getstringsize( s->text, FONT_UI, &w, &h);
+ lcd_clearrect(xmargin + s->startx*w/s->textlen,
+ ymargin + s->starty*h,
+ LCD_WIDTH - xmargin,
+ h);
+
+ /* restore scrolled row */
+ lcd_puts(s->startx,s->starty,s->text);
+ lcd_update();
+ }
+}
+
+void lcd_scroll_pause(void)
+{
+ scroll_count = 0;
+}
+
+void lcd_scroll_resume(void)
+{
+ scroll_count = 1;
+}
+
+void lcd_scroll_speed(int speed)
+{
+ scroll_speed = speed;
+}
+
+static void scroll_thread(void)
+{
+ struct scrollinfo* s = &scroll;
+
+ while ( 1 ) {
+ if ( !scroll_count ) {
+ yield();
+ continue;
+ }
+ /* wait 0.5s before starting scroll */
+ if ( scroll_count < scroll_speed/2 )
+ scroll_count++;
+ else {
+ int i;
+ int w, h;
+ for ( i=0; i<s->space-1; i++ )
+ s->line[i] = s->line[i+1];
+
+ if ( s->offset < s->textlen ) {
+ s->line[(int)s->space - 1] = s->text[(int)s->offset];
+ s->offset++;
+ }
+ else {
+ s->line[s->space - 1] = ' ';
+ if ( s->offset < s->textlen + scroll_spacing - 1 )
+ s->offset++;
+ else
+ s->offset = 0;
+ }
+
+ lcd_getstringsize( s->text, FONT_UI, &w, &h);
+ lcd_clearrect(xmargin + s->startx*w/s->textlen,
+ ymargin + s->starty*h,
+ LCD_WIDTH - xmargin,
+ h);
+
+ lcd_puts(s->startx,s->starty,s->line);
+ lcd_update();
+ }
+ sleep(HZ/scroll_speed);
+ }
+}
+
+#endif
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../rockbox-mode.el")
+ * end:
+ */
diff --git a/firmware/drivers/lcd.c b/firmware/drivers/lcd.c
index 2293191139..38dbe3cc2c 100644
--- a/firmware/drivers/lcd.c
+++ b/firmware/drivers/lcd.c
@@ -17,116 +17,24 @@
*
****************************************************************************/
-#include "config.h"
-#include "lcd.h"
-#include "kernel.h"
-#include "thread.h"
-#include <string.h>
-#include <stdlib.h>
-#include "file.h"
-#include "debug.h"
+#include <stdbool.h>
#include "system.h"
-#include "font.h"
-
-#if defined(SIMULATOR)
-#include "sim_icons.h"
-#endif
-
-/*** definitions ***/
#define LCDR (PBDR_ADDR+1)
#ifdef HAVE_LCD_CHARCELLS
-
#define LCD_DS 1 // PB0 = 1 --- 0001 --- LCD-DS
#define LCD_CS 2 // PB1 = 1 --- 0010 --- /LCD-CS
#define LCD_SD 4 // PB2 = 1 --- 0100 --- LCD-SD
#define LCD_SC 8 // PB3 = 1 --- 1000 --- LCD-SC
-#ifdef HAVE_NEW_CHARCELL_LCD
-# define LCD_CONTRAST_SET ((char)0x50)
-# define LCD_CRAM ((char)0x80) /* Characters */
-# define LCD_PRAM ((char)0xC0) /* Patterns */
-# define LCD_IRAM ((char)0x40) /* Icons */
#else
-# define LCD_CONTRAST_SET ((char)0xA8)
-# define LCD_CRAM ((char)0xB0) /* Characters */
-# define LCD_PRAM ((char)0x80) /* Patterns */
-# define LCD_IRAM ((char)0xE0) /* Icons */
-#endif
-#define LCD_CURSOR(x,y) ((char)(LCD_CRAM+((y)*16+(x))))
-#define LCD_ICON(i) ((char)(LCD_IRAM+i))
-
-#elif HAVE_LCD_BITMAP
-
#define LCD_SD 1 // PB0 = 1 --- 0001
#define LCD_SC 2 // PB1 = 1 --- 0010
#define LCD_RS 4 // PB2 = 1 --- 0100
#define LCD_CS 8 // PB3 = 1 --- 1000
#define LCD_DS LCD_RS
+#endif
-#define LCD_SET_LOWER_COLUMN_ADDRESS ((char)0x00)
-#define LCD_SET_HIGHER_COLUMN_ADDRESS ((char)0x10)
-#define LCD_SET_INTERNAL_REGULATOR_RESISTOR_RATIO ((char)0x20)
-#define LCD_SET_POWER_CONTROL_REGISTER ((char)0x28)
-#define LCD_SET_DISPLAY_START_LINE ((char)0x40)
-#define LCD_SET_CONTRAST_CONTROL_REGISTER ((char)0x81)
-#define LCD_SET_SEGMENT_REMAP ((char)0xA0)
-#define LCD_SET_LCD_BIAS ((char)0xA2)
-#define LCD_SET_ENTIRE_DISPLAY_OFF ((char)0xA4)
-#define LCD_SET_ENTIRE_DISPLAY_ON ((char)0xA5)
-#define LCD_SET_NORMAL_DISPLAY ((char)0xA6)
-#define LCD_SET_REVERSE_DISPLAY ((char)0xA7)
-#define LCD_SET_INDICATOR_OFF ((char)0xAC)
-#define LCD_SET_INDICATOR_ON ((char)0xAD)
-#define LCD_SET_DISPLAY_OFF ((char)0xAE)
-#define LCD_SET_DISPLAY_ON ((char)0xAF)
-#define LCD_SET_PAGE_ADDRESS ((char)0xB0)
-#define LCD_SET_COM_OUTPUT_SCAN_DIRECTION ((char)0xC0)
-#define LCD_SET_DISPLAY_OFFSET ((char)0xD3)
-#define LCD_SET_READ_MODIFY_WRITE_MODE ((char)0xE0)
-#define LCD_SOFTWARE_RESET ((char)0xE2)
-#define LCD_NOP ((char)0xE3)
-#define LCD_SET_END_OF_READ_MODIFY_WRITE_MODE ((char)0xEE)
-
-/* LCD command codes */
-#define LCD_CNTL_RESET 0xe2 // Software reset
-#define LCD_CNTL_POWER 0x2f // Power control
-#define LCD_CNTL_CONTRAST 0x81 // Contrast
-#define LCD_CNTL_OUTSCAN 0xc8 // Output scan direction
-#define LCD_CNTL_SEGREMAP 0xa1 // Segment remap
-#define LCD_CNTL_DISPON 0xaf // Display on
-
-#define LCD_CNTL_PAGE 0xb0 // Page address
-#define LCD_CNTL_HIGHCOL 0x10 // Upper column address
-#define LCD_CNTL_LOWCOL 0x00 // Lower column address
-
-
-#endif /* CHARCELL or BITMAP */
-
-
-/*** generic code ***/
-
-struct scrollinfo {
- char text[MAX_PATH];
- char line[32];
- int textlen;
- int offset;
- int startx;
- int starty;
- int space;
-};
-
-static void scroll_thread(void);
-static char scroll_stack[DEFAULT_STACK_SIZE];
-static char scroll_name[] = "scroll";
-static char scroll_speed = 8; /* updates per second */
-static char scroll_spacing = 3; /* spaces between end and start of text */
-
-
-static struct scrollinfo scroll; /* only one scroll line at the moment */
-static int scroll_count = 0;
-
-#ifndef SIMULATOR
/*
* About /CS,DS,SC,SD
* ------------------
@@ -174,12 +82,8 @@ static int scroll_count = 0;
*
*/
-#define ASM_IMPLEMENTATION
-
-static void lcd_write(bool command, int byte) __attribute__ ((section (".icode")));
-static void lcd_write(bool command, int byte)
-
-#ifdef ASM_IMPLEMENTATION
+void lcd_write(bool command, int byte) __attribute__ ((section (".icode")));
+void lcd_write(bool command, int byte)
{
asm("and.b %0, @(r0,gbr)"
:
@@ -206,26 +110,6 @@ static void lcd_write(bool command, int byte)
/* %4 */ "I"(LCD_SC),
/* %5 */ "z"(LCDR));
else
-#if 0
- asm ("shll8 %0\n"
- "0: \n\t"
- "and.b %2, @(r0,gbr)\n\t"
- "shll %0\n\t"
- "bf 1f\n\t"
- "or.b %3, @(r0,gbr)\n"
- "1: \n\t"
- "or.b %4, @(r0,gbr)\n"
- "add #-1, %1\n\t"
- "cmp/pl %1\n\t"
- "bt 0b"
- :
- : /* %0 */ "r"(((unsigned)byte)<<16),
- /* %1 */ "r"(8),
- /* %2 */ "I"(~(LCD_SC|LCD_SD)),
- /* %3 */ "I"(LCD_SD|LCD_DS),
- /* %4 */ "I"(LCD_SC|LCD_DS),
- /* %5 */ "z"(LCDR));
-#else
asm ("shll8 %0\n"
"0: \n\t"
"and.b %2, @(r0,gbr)\n\t"
@@ -283,975 +167,9 @@ static void lcd_write(bool command, int byte)
/* %3 */ "I"(LCD_SD|LCD_DS),
/* %4 */ "I"(LCD_SC|LCD_DS),
/* %5 */ "z"(LCDR));
-#endif
asm("or.b %0, @(r0,gbr)"
:
: /* %0 */ "I"(LCD_CS|LCD_DS|LCD_SD|LCD_SC),
/* %1 */ "z"(LCDR));
}
-#else
-{
- int i;
- char on,off;
-
- PBDR &= ~LCD_CS; /* enable lcd chip select */
-
- if ( command ) {
- on=~(LCD_SD|LCD_SC|LCD_DS);
- off=LCD_SC;
- }
- else {
- on=~(LCD_SD|LCD_SC);
- off=LCD_SC|LCD_DS;
- }
-
- /* clock out each bit, MSB first */
- for (i=0x80;i;i>>=1)
- {
- PBDR &= on;
- if (i & byte)
- PBDR |= LCD_SD;
- PBDR |= off;
- }
-
- PBDR |= LCD_CS; /* disable lcd chip select */
-}
-#endif /* ASM_IMPLEMENTATION */
-#endif /* !SIMULATOR */
-
-/*** model specific code */
-
-#ifdef HAVE_LCD_CHARCELLS
-
-#ifdef HAVE_NEW_CHARCELL_LCD
-
-static const unsigned char lcd_ascii[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
- 0x10,0x11,0x05,0x13,0x14,0x15,0x16,0x17,
- 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
- 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
- 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
- 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
- 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
- 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
- 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
- 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
- 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
- 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
- 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
- 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
- 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
- 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
- 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
- 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
- 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
- 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
- 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,
- 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
- 0x41,0x41,0x41,0x41,0x41,0x41,0x20,0x43,
- 0x45,0x45,0x45,0x45,0x49,0x49,0x49,0x49,
- 0x44,0x4e,0x4f,0x4f,0x4f,0x4f,0x4f,0x20,
- 0x20,0x55,0x55,0x55,0x55,0x59,0x20,0x20,
- 0x61,0x61,0x61,0x61,0x61,0x61,0x20,0x63,
- 0x65,0x65,0x65,0x65,0x69,0x69,0x69,0x69,
- 0x6f,0x6e,0x6f,0x6f,0x6f,0x6f,0x6f,0x20,
- 0x20,0x75,0x75,0x75,0x75,0x79,0x20,0x79
-};
-
-#else
-
-static const unsigned char lcd_ascii[] = {
- 0x00,0x01,0x02,0x03,0x00,0x84,0x85,0x89,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0xec,0xe3,0xe2,0xe1,0xe0,0xdf,0x15,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x24,0x25,0x26,0x37,0x06,0x29,0x2a,0x2b,
- 0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,
- 0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,
- 0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,
- 0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,
- 0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,
- 0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,
- 0x5c,0x5d,0x5e,0xa9,0x33,0xce,0x00,0x15,
- 0x00,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
- 0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
- 0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,
- 0x7c,0x7d,0x7e,0x24,0x24,0x24,0x24,0x24,
- 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
- 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
- 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
- 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
- 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
- 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
- 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,
- 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
- 0x45,0x45,0x45,0x45,0x45,0x45,0x24,0x47,
- 0x49,0x49,0x49,0x49,0x4d,0x4d,0x4d,0x4d,
- 0x48,0x52,0x53,0x53,0x53,0x53,0x53,0x24,
- 0x24,0x59,0x59,0x59,0x59,0x5d,0x24,0x24,
- 0x65,0x65,0x65,0x65,0x65,0x65,0x24,0x67,
- 0x69,0x69,0x69,0x69,0x6d,0x6d,0x6d,0x6d,
- 0x73,0x72,0x73,0x73,0x73,0x73,0x73,0x24,
- 0x24,0x79,0x79,0x79,0x79,0x7d,0x24,0x7d
-};
-#endif /* HAVE_NEW_CHARCELL_LCD */
-
-#ifndef SIMULATOR
-void lcd_clear_display(void)
-{
- int i;
- lcd_write(true,LCD_CURSOR(0,0));
- for (i=0;i<32;i++)
- lcd_write(false,lcd_ascii[' ']);
-}
-
-void lcd_puts(int x, int y, unsigned char *string)
-{
- int i;
- lcd_write(true,LCD_CURSOR(x,y));
- for (i=0; *string && x++<11; i++)
- lcd_write(false,lcd_ascii[*(unsigned char*)string++]);
- for (; x<11; x++)
- lcd_write(false,lcd_ascii[' ']);
-}
-
-void lcd_putc(int x, int y, unsigned char ch)
-{
- lcd_write(true,LCD_CURSOR(x,y));
- lcd_write(false,lcd_ascii[ch]);
-}
-
-void lcd_define_pattern (int which,char *pattern,int length)
-{
- int i;
- lcd_write(true,LCD_PRAM|which);
- for (i=0;i<length;i++)
- lcd_write(false,pattern[i]);
-}
-
-void lcd_double_height(bool on)
-{
- lcd_write(true,on?9:8);
-}
-
-static char icon_pos[] =
-{
- 0, 0, 0, 0, /* Battery */
- 2, /* USB */
- 3, /* Play */
- 4, /* Record */
- 5, /* Pause */
- 5, /* Audio */
- 6, /* Repeat */
- 7, /* 1 */
- 9, /* Volume */
- 9, /* Volume 1 */
- 9, /* Volume 2 */
- 10, /* Volume 3 */
- 10, /* Volume 4 */
- 10, /* Volume 5 */
- 10, /* Param */
-};
-
-static char icon_mask[] =
-{
- 0x02, 0x08, 0x04, 0x10, /* Battery */
- 0x04, /* USB */
- 0x10, /* Play */
- 0x10, /* Record */
- 0x02, /* Pause */
- 0x10, /* Audio */
- 0x02, /* Repeat */
- 0x01, /* 1 */
- 0x04, /* Volume */
- 0x02, /* Volume 1 */
- 0x01, /* Volume 2 */
- 0x08, /* Volume 3 */
- 0x04, /* Volume 4 */
- 0x01, /* Volume 5 */
- 0x10, /* Param */
-};
-
-void lcd_icon(int icon, bool enable)
-{
- static unsigned char icon_mirror[11] = {0};
- int pos, mask;
-
- pos = icon_pos[icon];
- mask = icon_mask[icon];
-
- lcd_write(true, LCD_ICON(pos));
-
- if(enable)
- icon_mirror[pos] |= mask;
- else
- icon_mirror[pos] &= ~mask;
-
- lcd_write(false, icon_mirror[pos]);
-}
-#endif /* !SIMULATOR */
-
-#endif /* HAVE_LCD_CHARCELLS */
-
-#if defined(SIMULATOR) && defined(HAVE_LCD_CHARCELLS)
-void lcd_icon(int icon, bool enable)
-{
- sim_lcd_icon(icon, enable);
-}
-#endif
-
-#if defined(HAVE_LCD_CHARCELLS) || defined(SIMULATOR) /* not BITMAP */
-void lcd_init (void)
-{
- create_thread(scroll_thread, scroll_stack,
- sizeof(scroll_stack), scroll_name);
-}
-#endif
-
-#ifdef SIMULATOR
-void lcd_set_contrast(int val)
-{
- val = val;
-}
-#else
-#ifdef HAVE_LCD_BITMAP
-void lcd_set_contrast(int val)
-{
- lcd_write(true, LCD_CNTL_CONTRAST);
- lcd_write(true, val);
-}
-#else
-void lcd_set_contrast(int val)
-{
- lcd_write(true, LCD_CONTRAST_SET);
- lcd_write(false, 31-val);
-}
-#endif
-#endif
-
-#if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR) /* not CHARCELLS */
-
-/*
- * All bitmaps have this format:
- * Bits within a byte are arranged veritcally, LSB at top.
- * Bytes are stored in column-major format, with byte 0 at top left,
- * byte 1 is 2nd from top, etc. Bytes following left-most column
- * starts 2nd left column, etc.
- *
- * Note: The HW takes bitmap bytes in row-major order.
- *
- * Memory copy of display bitmap
- */
-unsigned char lcd_framebuffer[LCD_WIDTH][LCD_HEIGHT/8];
-
-static int xmargin=0;
-static int ymargin=0;
-
-/*
- * ASCII character generation tables
- *
- * This contains only the printable characters (0x20-0x7f).
- * Each element in this table is a character pattern bitmap.
- */
-#define ASCII_MIN 0x20 /* First char in table */
-#define ASCII_MAX 0x7f /* Last char in table */
-
-/* All zeros and ones bitmaps for area filling */
-static unsigned char zeros[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00 };
-static unsigned char ones[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff };
-
-#ifndef SIMULATOR
-
-/*
- * Initialize LCD
- */
-void lcd_init (void)
-{
- /* Initialize PB0-3 as output pins */
- PBCR2 &= 0xff00; /* MD = 00 */
- PBIOR |= 0x000f; /* IOR = 1 */
-
- lcd_clear_display();
- lcd_update();
- create_thread(scroll_thread, scroll_stack,
- sizeof(scroll_stack), scroll_name);
-}
-
-/*
- * Update the display.
- * This must be called after all other LCD functions that change the display.
- */
-void lcd_update (void) __attribute__ ((section (".icode")));
-void lcd_update (void)
-{
- int x, y;
-
- /* Copy display bitmap to hardware */
- for (y = 0; y < LCD_HEIGHT/8; y++)
- {
- lcd_write (true, LCD_CNTL_PAGE | (y & 0xf));
- lcd_write (true, LCD_CNTL_HIGHCOL);
- lcd_write (true, LCD_CNTL_LOWCOL);
-
- for (x = 0; x < LCD_WIDTH; x++)
- lcd_write (false, lcd_framebuffer[x][y]);
- }
-}
-
-/*
- * Update a fraction of the display.
- */
-void lcd_update_rect (int, int, int, int) __attribute__ ((section (".icode")));
-void lcd_update_rect (int x_start, int y,
- int width, int height)
-{
- int ymax;
- int xmax;
- int x;
-
- /* The Y coordinates have to work on even 8 pixel rows */
- ymax = (y + height)/8;
- y /= 8;
-
- xmax = x_start + width;
-
- if(xmax > LCD_WIDTH)
- xmax = LCD_WIDTH;
- if(ymax >= LCD_HEIGHT/8)
- ymax = LCD_HEIGHT/8-1;
-
- /* Copy specified rectange bitmap to hardware */
- for (; y <= ymax; y++)
- {
- lcd_write (true, LCD_CNTL_PAGE | (y & 0xf));
- lcd_write (true, LCD_CNTL_HIGHCOL | ((x_start>>4) & 0xf));
- lcd_write (true, LCD_CNTL_LOWCOL | (x_start & 0xf));
-
- for (x = x_start; x < xmax; x++)
- lcd_write (false, lcd_framebuffer[x][y]);
- }
-}
-
-#endif /* SIMULATOR */
-
-/*
- * Clear the display
- */
-void lcd_clear_display (void)
-{
-#if defined(SIMULATOR) && defined(HAVE_LCD_CHARCELLS)
- /* Clear just the text portion of the display */
- int x, y;
- for (y = 8; y <= (32 + 7); ++y)
- {
- for (x = 0; x < LCD_WIDTH; x++)
- CLEAR_PIXEL(x, y);
- }
- /* this function is being used when simulating a charcell LCD and
- then we update immediately */
- lcd_update();
-#else
- memset (lcd_framebuffer, 0, sizeof lcd_framebuffer);
-#endif
-}
-
-void lcd_setmargins(int x, int y)
-{
- xmargin = x;
- ymargin = y;
-}
-
-int lcd_getxmargin(void)
-{
- return xmargin;
-}
-
-int lcd_getymargin(void)
-{
- return ymargin;
-}
-
-static int curfont = FONT_SYSFIXED;
-
-/*
- * Put a string at specified character position
- */
-void lcd_puts(int x, int y, unsigned char *str)
-{
- int xpos,ypos,w,h;
-
-#if defined(SIMULATOR) && defined(HAVE_LCD_CHARCELLS)
- /* We make the simulator truncate the string if it reaches the right edge,
- as otherwise it'll wrap. The real target doesn't wrap. */
-
- char buffer[12];
- if(strlen(str)+x > 11 ) {
- strncpy(buffer, str, sizeof buffer);
- buffer[11-x]=0;
- str = buffer;
- }
- xmargin = 0;
- ymargin = 8;
-#endif
-
- if(!str || !str[0])
- return;
-
- lcd_getstringsize(str, curfont, &w, &h);
- xpos = xmargin + x*w / strlen(str);
- ypos = ymargin + y*h;
- lcd_putsxy( xpos, ypos, str, curfont);
- lcd_clearrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h);
-#if defined(SIMULATOR) && defined(HAVE_LCD_CHARCELLS)
- /* this function is being used when simulating a charcell LCD and
- then we update immediately */
- lcd_update();
-#endif
-}
-
-/* set current font*/
-void lcd_setfont(int newfont)
-{
- curfont = newfont;
-}
-
-/*
- * Return width and height of a given font.
- */
-void lcd_getfontsize(int font, int *width, int *height)
-{
- struct font* pf = font_get(font);
-
- *width = pf->maxwidth;
- *height = pf->height;
-}
-
-
-/*
- * Return width and height of a given font.
- */
-int lcd_getstringsize(unsigned char *str, int font, int *w, int *h)
-{
- struct font* pf = font_get(font);
- int ch;
- int width = 0;
-
- while((ch = *str++)) {
- /* check input range*/
- if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
- ch = pf->defaultchar;
- ch -= pf->firstchar;
-
- /* get proportional width and glyph bits*/
- width += pf->width? pf->width[ch]: pf->maxwidth;
- }
- *w = width;
- *h = pf->height;
-
- return width;
-}
-
-/*
- * Put a string at specified bit position
- */
-void lcd_putsxy(int x, int y, unsigned char *str, int font)
-{
- int ch;
- struct font* pf = font_get(font);
-
- while (((ch = *str++) != '\0')) {
- bitmap_t *bits;
- int width;
-
- /* check input range*/
- if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
- ch = pf->defaultchar;
- ch -= pf->firstchar;
-
- /* get proportional width and glyph bits*/
- width = pf->width ? pf->width[ch] : pf->maxwidth;
- if (x + width > LCD_WIDTH)
- break;
-
- /* no partial-height drawing for now...*/
- if (y + pf->height > LCD_HEIGHT)
- break;
- bits = pf->bits + (pf->offset ? pf->offset[ch] : (pf->height * ch));
-
- lcd_bitmap((unsigned char *)bits, x, y, width, pf->height, true);
- x += width;
- }
-}
-
-/*
- * Display a bitmap at (x, y), size (nx, ny)
- * clear is true to clear destination area first
- */
-void lcd_bitmap (unsigned char *src, int x, int y, int nx, int ny,
- bool clear) __attribute__ ((section (".icode")));
-void lcd_bitmap (unsigned char *src, int x, int y, int nx, int ny,
- bool clear)
-{
- unsigned char *dst;
- unsigned char *dst2;
- unsigned int data, mask, mask2, mask3, mask4;
- int shift;
-
- if (((unsigned)x >= LCD_WIDTH) || ((unsigned)y >= LCD_HEIGHT))
- return;
- if (((unsigned)(x + nx)) >= LCD_WIDTH)
- nx = LCD_WIDTH - x;
- if (((unsigned)(y + ny)) >= LCD_HEIGHT)
- ny = LCD_HEIGHT - y;
-
- shift = y & 7;
- dst2 = &lcd_framebuffer[x][y/8];
- ny += shift;
-
- /* Calculate bit masks */
- mask4 = ~(0xfe << ((ny-1) & 7));
- if (clear)
- {
- mask = ~(0xff << shift);
- mask2 = 0;
- mask3 = ~mask4;
- if (ny <= 8)
- mask3 |= mask;
- }
- else
- mask = mask2 = mask3 = 0xff;
-
- /* Loop for each column */
- for (x = 0; x < nx; x++)
- {
- dst = dst2;
- dst2 += LCD_HEIGHT/8;
- data = 0;
- y = 0;
-
- if (ny > 8)
- {
- /* First partial row */
- data = *src++ << shift;
- *dst = (*dst & mask) | data;
- data >>= 8;
- dst++;
-
- /* Intermediate rows */
- for (y = 8; y < ny-8; y += 8)
- {
- data |= *src++ << shift;
- *dst = (*dst & mask2) | data;
- data >>= 8;
- dst++;
- }
- }
-
- /* Last partial row */
- if (y + shift < ny)
- data |= *src++ << shift;
- *dst = (*dst & mask3) | (data & mask4);
- }
-}
-
-/*
- * Draw a rectangle with point a (upper left) at (x, y)
- * and size (nx, ny)
- */
-void lcd_drawrect (int x, int y, int nx, int ny)
-{
- int i;
-
- if (x > LCD_WIDTH)
- return;
- if (y > LCD_HEIGHT)
- return;
-
- if (x + nx > LCD_WIDTH)
- nx = LCD_WIDTH - x;
- if (y + ny > LCD_HEIGHT)
- ny = LCD_HEIGHT - y;
-
- /* vertical lines */
- for (i = 0; i < ny; i++) {
- DRAW_PIXEL(x, (y + i));
- DRAW_PIXEL((x + nx - 1), (y + i));
- }
-
- /* horizontal lines */
- for (i = 0; i < nx; i++) {
- DRAW_PIXEL((x + i),y);
- DRAW_PIXEL((x + i),(y + ny - 1));
- }
-}
-
-/*
- * Clear a rectangular area at (x, y), size (nx, ny)
- */
-void lcd_clearrect (int x, int y, int nx, int ny)
-{
- int i;
- for (i = 0; i < nx; i++)
- lcd_bitmap (zeros, x+i, y, 1, ny, true);
-}
-
-/*
- * Fill a rectangular area at (x, y), size (nx, ny)
- */
-void lcd_fillrect (int x, int y, int nx, int ny)
-{
- int i;
- for (i = 0; i < nx; i++)
- lcd_bitmap (ones, x+i, y, 1, ny, true);
-}
-
-/* Invert a rectangular area at (x, y), size (nx, ny) */
-void lcd_invertrect (int x, int y, int nx, int ny)
-{
- int i, j;
-
- if (x > LCD_WIDTH)
- return;
- if (y > LCD_HEIGHT)
- return;
-
- if (x + nx > LCD_WIDTH)
- nx = LCD_WIDTH - x;
- if (y + ny > LCD_HEIGHT)
- ny = LCD_HEIGHT - y;
-
- for (i = 0; i < nx; i++)
- for (j = 0; j < ny; j++)
- INVERT_PIXEL((x + i), (y + j));
-}
-
-void lcd_drawline( int x1, int y1, int x2, int y2 )
-{
- int numpixels;
- int i;
- int deltax, deltay;
- int d, dinc1, dinc2;
- int x, xinc1, xinc2;
- int y, yinc1, yinc2;
-
- deltax = abs(x2 - x1);
- deltay = abs(y2 - y1);
-
- if(deltax >= deltay)
- {
- numpixels = deltax;
- d = 2 * deltay - deltax;
- dinc1 = deltay * 2;
- dinc2 = (deltay - deltax) * 2;
- xinc1 = 1;
- xinc2 = 1;
- yinc1 = 0;
- yinc2 = 1;
- }
- else
- {
- numpixels = deltay;
- d = 2 * deltax - deltay;
- dinc1 = deltax * 2;
- dinc2 = (deltax - deltay) * 2;
- xinc1 = 0;
- xinc2 = 1;
- yinc1 = 1;
- yinc2 = 1;
- }
- numpixels++; /* include endpoints */
-
- if(x1 > x2)
- {
- xinc1 = -xinc1;
- xinc2 = -xinc2;
- }
-
- if(y1 > y2)
- {
- yinc1 = -yinc1;
- yinc2 = -yinc2;
- }
-
- x = x1;
- y = y1;
-
- for(i=0; i<numpixels; i++)
- {
- DRAW_PIXEL(x,y);
-
- if(d < 0)
- {
- d += dinc1;
- x += xinc1;
- y += yinc1;
- }
- else
- {
- d += dinc2;
- x += xinc2;
- y += yinc2;
- }
- }
-}
-
-void lcd_clearline( int x1, int y1, int x2, int y2 )
-{
- int numpixels;
- int i;
- int deltax, deltay;
- int d, dinc1, dinc2;
- int x, xinc1, xinc2;
- int y, yinc1, yinc2;
-
- deltax = abs(x2 - x1);
- deltay = abs(y2 - y1);
-
- if(deltax >= deltay)
- {
- numpixels = deltax;
- d = 2 * deltay - deltax;
- dinc1 = deltay * 2;
- dinc2 = (deltay - deltax) * 2;
- xinc1 = 1;
- xinc2 = 1;
- yinc1 = 0;
- yinc2 = 1;
- }
- else
- {
- numpixels = deltay;
- d = 2 * deltax - deltay;
- dinc1 = deltax * 2;
- dinc2 = (deltax - deltay) * 2;
- xinc1 = 0;
- xinc2 = 1;
- yinc1 = 1;
- yinc2 = 1;
- }
- numpixels++; /* include endpoints */
-
- if(x1 > x2)
- {
- xinc1 = -xinc1;
- xinc2 = -xinc2;
- }
-
- if(y1 > y2)
- {
- yinc1 = -yinc1;
- yinc2 = -yinc2;
- }
-
- x = x1;
- y = y1;
-
- for(i=0; i<numpixels; i++)
- {
- CLEAR_PIXEL(x,y);
-
- if(d < 0)
- {
- d += dinc1;
- x += xinc1;
- y += yinc1;
- }
- else
- {
- d += dinc2;
- x += xinc2;
- y += yinc2;
- }
- }
-}
-
-/*
- * Set a single pixel
- */
-void lcd_drawpixel(int x, int y)
-{
- DRAW_PIXEL(x,y);
-}
-
-/*
- * Clear a single pixel
- */
-void lcd_clearpixel(int x, int y)
-{
- CLEAR_PIXEL(x,y);
-}
-
-/*
- * Invert a single pixel
- */
-void lcd_invertpixel(int x, int y)
-{
- INVERT_PIXEL(x,y);
-}
-
-#else
-/* no LCD defined, no code to use */
-#endif
-
-void lcd_puts_scroll(int x, int y, unsigned char* string )
-{
- struct scrollinfo* s = &scroll;
-#ifdef HAVE_LCD_CHARCELLS
- s->space = 11 - x;
-#else
- unsigned char ch[2];
- int w, h;
- int width, height;
- lcd_getfontsize(curfont, &width, &height);
-
- ch[1] = 0; /* zero terminate */
- ch[0] = string[0];
- width = 0;
- s->space = 0;
- while ( ch[0] &&
- (width + lcd_getstringsize(ch, curfont, &w, &h) <
- (LCD_WIDTH - x*8))) {
- width += w;
- s->space++;
- ch[0]=string[s->space];
- }
-#endif
-
- lcd_puts(x,y,string);
- s->textlen = strlen(string);
-
-#ifdef HAVE_LCD_BITMAP
- s->space += 2;
- lcd_getstringsize(string,curfont,&w,&h);
- if ( w > LCD_WIDTH - xmargin ) {
-#else
- if ( s->textlen > s->space ) {
-#endif
- s->offset=s->space;
- s->startx=x;
- s->starty=y;
- strncpy(s->text,string,sizeof s->text);
- s->text[sizeof s->text - 1] = 0;
- memset(s->line, 0, sizeof s->line);
- strncpy(s->line,string,
- s->space > (int)sizeof s->line ?
- (int)sizeof s->line : s->space );
- s->line[sizeof s->line - 1] = 0;
- scroll_count = 1;
- }
-}
-
-
-void lcd_stop_scroll(void)
-{
- if ( scroll_count ) {
- struct scrollinfo* s = &scroll;
- scroll_count = 0;
-
-#ifdef HAVE_LCD_BITMAP
- {
- int w,h;
- /* FIXME no font index */
- lcd_getstringsize( s->text, FONT_UI, &w, &h);
- lcd_clearrect(xmargin + s->startx*w/s->textlen,
- ymargin + s->starty*h,
- LCD_WIDTH - xmargin,
- h);
- }
-#endif
- /* restore scrolled row */
- lcd_puts(s->startx,s->starty,s->text);
- lcd_update();
- }
-}
-
-void lcd_scroll_pause(void)
-{
- scroll_count = 0;
-}
-
-void lcd_scroll_resume(void)
-{
- scroll_count = 1;
-}
-
-void lcd_scroll_speed(int speed)
-{
- scroll_speed = speed;
-}
-
-static void scroll_thread(void)
-{
- struct scrollinfo* s = &scroll;
-
- while ( 1 ) {
- if ( !scroll_count ) {
- yield();
- continue;
- }
- /* wait 0.5s before starting scroll */
- if ( scroll_count < scroll_speed/2 )
- scroll_count++;
- else {
- int i;
- for ( i=0; i<s->space-1; i++ )
- s->line[i] = s->line[i+1];
-
- if ( s->offset < s->textlen ) {
- s->line[(int)s->space - 1] = s->text[(int)s->offset];
- s->offset++;
- }
- else {
- s->line[s->space - 1] = ' ';
- if ( s->offset < s->textlen + scroll_spacing - 1 )
- s->offset++;
- else
- s->offset = 0;
- }
-
-#ifdef HAVE_LCD_BITMAP
- {
- /* FIXME no font index */
- int w, h;
- lcd_getstringsize( s->text, FONT_UI, &w, &h);
- lcd_clearrect(xmargin + s->startx*w/s->textlen,
- ymargin + s->starty*h,
- LCD_WIDTH - xmargin,
- h);
- }
-#endif
- lcd_puts(s->startx,s->starty,s->line);
- lcd_update();
- }
- sleep(HZ/scroll_speed);
- }
-}
-
-#ifndef SIMULATOR
-#ifdef HAVE_LCD_BITMAP
-/**
- * Rolls up the lcd display by the specified amount of lines.
- * Lines that are rolled out over the top of the screen are
- * rolled in from the bottom again. This is a hardware
- * remapping only and all operations on the lcd are affected.
- * ->
- * @param int lines - The number of lines that are rolled.
- * The value must be 0 <= pixels < LCD_HEIGHT.
- */
-void lcd_roll(int lines)
-{
- lcd_write(true, LCD_SET_DISPLAY_START_LINE | (lines & (LCD_HEIGHT-1)));
-}
-#endif
-#endif
-
-/* -----------------------------------------------------------------
- * local variables:
- * eval: (load-file "../rockbox-mode.el")
- * end:
- */
diff --git a/firmware/drivers/lcd.h b/firmware/drivers/lcd.h
index 388f31c1cf..76e38375e4 100644
--- a/firmware/drivers/lcd.h
+++ b/firmware/drivers/lcd.h
@@ -37,6 +37,7 @@ extern void lcd_icon(int icon, bool enable);
extern void lcd_stop_scroll(void);
extern void lcd_scroll_speed( int speed );
extern void lcd_set_contrast(int val);
+extern void lcd_write( bool command, int byte );
#if defined(SIMULATOR) || defined(HAVE_LCD_BITMAP)
extern void lcd_update(void);