summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugin.c7
-rw-r--r--apps/plugin.h8
-rw-r--r--apps/plugins/doom/i_video.c95
-rw-r--r--apps/plugins/plugin.lds20
-rw-r--r--firmware/export/config-mrobe500.h37
-rw-r--r--firmware/export/lcd.h7
-rw-r--r--firmware/target/arm/tms320dm320/app.lds57
-rw-r--r--firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c241
8 files changed, 336 insertions, 136 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index 17e9ac6..087bf74 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -636,6 +636,13 @@ static const struct plugin_api rockbox_api = {
#if defined(HAVE_LCD_MODES)
lcd_set_mode,
#endif
+
+#if defined(HAVE_LCD_MODES)
+#if HAVE_LCD_MODES & LCD_MODE_PAL256
+ lcd_blit_pal256,
+ lcd_pal256_update_pal,
+#endif
+#endif
};
int plugin_load(const char* plugin, const void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index fdcf3c2..d38cc42 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -794,6 +794,14 @@ struct plugin_api {
#if defined(HAVE_LCD_MODES)
void (*lcd_set_mode)(int mode);
#endif
+
+#if defined(HAVE_LCD_MODES)
+#if HAVE_LCD_MODES & LCD_MODE_PAL256
+ void (*lcd_blit_pal256)(unsigned char *src, int src_x, int src_y, int x, int y,
+ int width, int height);
+ void (*lcd_pal256_update_pal)(fb_data *palette);
+#endif
+#endif
};
/* plugin header */
diff --git a/apps/plugins/doom/i_video.c b/apps/plugins/doom/i_video.c
index c148d17..418fcd4 100644
--- a/apps/plugins/doom/i_video.c
+++ b/apps/plugins/doom/i_video.c
@@ -140,6 +140,12 @@ static fb_data *paldata=NULL;
//
void I_ShutdownGraphics(void)
{
+#if defined(HAVE_LCD_MODES)
+#if (HAVE_LCD_MODES & LCD_MODE_PAL256)
+ rb->lcd_set_mode(LCD_MODE_RGB565);
+#endif
+#endif
+
#ifndef HAVE_LCD_COLOR
grey_release();
#endif
@@ -597,13 +603,19 @@ static void I_UploadNewPalette(int pal)
}
#ifdef RANGECHECK
- if ((size_t)pal >= num_pals)
- I_Error("I_UploadNewPalette: Palette number out of range (%d>=%d)",
- pal, num_pals);
+ if ((size_t)pal >= num_pals)
+ I_Error("I_UploadNewPalette: Palette number out of range (%d>=%d)",
+ pal, num_pals);
#endif
- memcpy(palette,paldata+256*pal,256*sizeof(fb_data));
-}
+ memcpy(palette,paldata+256*pal,256*sizeof(fb_data));
+
+#if defined(HAVE_LCD_MODES)
+#if (HAVE_LCD_MODES & LCD_MODE_PAL256)
+ rb->lcd_pal256_update_pal(paldata+256*pal);
+#endif
+#endif
+}
//
// I_FinishUpdate
@@ -613,36 +625,37 @@ void I_FinishUpdate (void)
{
int count;
byte *src = d_screens[0];
+
#if (CONFIG_LCD == LCD_H300) && !defined(SIMULATOR)
count = SCREENWIDTH*SCREENHEIGHT;
/* ASM screen update (drops ~300 tics) */
asm volatile (
- "move.w #33, (%[LCD]) \n" /* Setup the LCD controller */
- "nop \n"
- "clr.w (%[LCD2]) \n"
- "nop \n"
- "move.w #34, (%[LCD]) \n" /* End LCD controller setup */
- "clr.l %%d1 \n"
- ".loop: \n"
- "move.l (%[scrp])+, %%d0 \n"
- "swap.w %%d0 \n"
- "move.w %%d0, %%d1 \n"
- "lsr.l #8,%%d1 \n"
- "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n"
- "move.b %%d0,%%d1 \n"
- "swap.w %%d0 \n"
- "nop \n"
- "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n"
- "move.w %%d0, %%d1 \n"
- "lsr.l #8,%%d1 \n"
- "nop \n"
- "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n"
- "move.b %%d0,%%d1 \n"
- "nop \n"
- "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n"
- "subq.l #4,%[cnt] \n"
- "bne.b .loop \n"
+ "move.w #33, (%[LCD]) \n" /* Setup the LCD controller */
+ "nop \n"
+ "clr.w (%[LCD2]) \n"
+ "nop \n"
+ "move.w #34, (%[LCD]) \n" /* End LCD controller setup */
+ "clr.l %%d1 \n"
+ ".loop: \n"
+ "move.l (%[scrp])+, %%d0 \n"
+ "swap.w %%d0 \n"
+ "move.w %%d0, %%d1 \n"
+ "lsr.l #8,%%d1 \n"
+ "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n"
+ "move.b %%d0,%%d1 \n"
+ "swap.w %%d0 \n"
+ "nop \n"
+ "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n"
+ "move.w %%d0, %%d1 \n"
+ "lsr.l #8,%%d1 \n"
+ "nop \n"
+ "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n"
+ "move.b %%d0,%%d1 \n"
+ "nop \n"
+ "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n"
+ "subq.l #4,%[cnt] \n"
+ "bne.b .loop \n"
: /* outputs */
[scrp]"+a"(src),
[cnt] "+d"(count)
@@ -713,7 +726,14 @@ void I_FinishUpdate (void)
"d0", "d1", "d2", "d3"
);
#else
-#ifdef HAVE_LCD_COLOR
+
+/* If the hardware has support for a paletted mode it takes precidence */
+#if defined(HAVE_LCD_MODES)
+#if (HAVE_LCD_MODES & LCD_MODE_PAL256)
+ (void) count;
+ rb->lcd_blit_pal256(src, 0, 0, 0, 0, LCD_WIDTH, LCD_HEIGHT);
+#endif
+#elif defined(HAVE_LCD_COLOR)
#if(LCD_HEIGHT>LCD_WIDTH)
if(rotate_screen)
{
@@ -742,8 +762,9 @@ void I_FinishUpdate (void)
*dst++ = palette[*src++];
while (--count);
}
- rb->lcd_update();
+ rb->lcd_update();
#else /* !HAVE_LCD_COLOR */
+
unsigned char *dst;
int y;
@@ -758,8 +779,8 @@ void I_FinishUpdate (void)
grey_ub_gray_bitmap(greybuffer, 0, y, SCREENWIDTH, 1);
}
-#endif /* !HAVE_LCD_COLOR */
-#endif
+#endif
+#endif
}
//
@@ -786,6 +807,12 @@ void I_InitGraphics(void)
printf("Starting Graphics engine\n");
noprintf=1;
+
+#if defined(HAVE_LCD_MODES)
+#if (HAVE_LCD_MODES & LCD_MODE_PAL256)
+ rb->lcd_set_mode(LCD_MODE_PAL256);
+#endif
+#endif
/* Note: The other screens are allocated as needed */
diff --git a/apps/plugins/plugin.lds b/apps/plugins/plugin.lds
index 9c65f31..d6f6234 100644
--- a/apps/plugins/plugin.lds
+++ b/apps/plugins/plugin.lds
@@ -35,18 +35,20 @@ OUTPUT_FORMAT(elf32-littlemips)
#define NOCACHE_BASE 0x00000000
#endif
-#if CONFIG_CPU==DM320 || CONFIG_CPU==S3C2440
-#define LCD_BUFFER_SIZE (LCD_WIDTH*LCD_HEIGHT*2)
+#if CONFIG_CPU==DM320 || CONFIG_CPU==IMX31L
+/* Give this 1 meg to allow it to align to the MMU boundary */
+#define LCD_TTB_AREA 0x100000
+#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_TTB_AREA
+#elif CONFIG_CPU==S3C2440
+#define LCD_BUFFER_SIZE (LCD_WIDTH*LCD_HEIGHT*2)
/* must be 16Kb (0x4000) aligned */
#define TTB_SIZE (0x4000)
#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_BUFFER_SIZE - TTB_SIZE
-#elif CONFIG_CPU==IMX31L
-#include "imx31l.h"
-/* Reserve 1mb for LCD buffer/TTB as in app.lds */
-#define DRAMSIZE (MEMORYSIZE * 0x100000 - 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET - CODEC_SIZE
+
#elif CONFIG_CPU==AS3525 && MEMORYSIZE <= 2
#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET
+
#else
#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET - CODEC_SIZE
#endif
@@ -77,11 +79,7 @@ OUTPUT_FORMAT(elf32-littlemips)
#define DRAMORIG 0xc00000 + STUBOFFSET
#define IRAMORIG 0x407000
#define IRAMSIZE 0x9000
-#elif CONFIG_CPU == S3C2440
-#define DRAMORIG 0x0 + STUBOFFSET
-#define IRAM DRAM
-#define IRAMSIZE 0
-#elif CONFIG_CPU == IMX31L
+#elif CONFIG_CPU == IMX31L || CONFIG_CPU == S3C2440
#define DRAMORIG 0x0 + STUBOFFSET
#define IRAM DRAM
#define IRAMSIZE 0
diff --git a/firmware/export/config-mrobe500.h b/firmware/export/config-mrobe500.h
index fafea48..90bbefe 100644
--- a/firmware/export/config-mrobe500.h
+++ b/firmware/export/config-mrobe500.h
@@ -59,24 +59,21 @@
/* LCD dimensions */
#define CONFIG_LCD LCD_MROBE500
-/* choose the lcd orientation. both work */
-/* #define CONFIG_ORIENTATION SCREEN_PORTRAIT */
-#define CONFIG_ORIENTATION SCREEN_PORTRAIT
-
-#if 1
-#define NATIVE_MAX_WIDTH 480
-#define NATIVE_MAX_HEIGHT 640
+#if 0
+#define LCD_NATIVE_WIDTH 480
+#define LCD_NATIVE_HEIGHT 640
#else
-#define NATIVE_MAX_WIDTH 240
-#define NATIVE_MAX_HEIGHT 320
+#define LCD_NATIVE_WIDTH 240
+#define LCD_NATIVE_HEIGHT 320
#endif
-#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
-#define LCD_WIDTH NATIVE_MAX_WIDTH
-#define LCD_HEIGHT NATIVE_MAX_HEIGHT
+/* choose the lcd orientation. CONFIG_ORIENTATION defined in config.h */
+#if 0
+#define LCD_WIDTH LCD_NATIVE_WIDTH
+#define LCD_HEIGHT LCD_NATIVE_HEIGHT
#else
-#define LCD_WIDTH NATIVE_MAX_HEIGHT
-#define LCD_HEIGHT NATIVE_MAX_WIDTH
+#define LCD_WIDTH LCD_NATIVE_HEIGHT
+#define LCD_HEIGHT LCD_NATIVE_WIDTH
#endif
#define LCD_DEPTH 16 /* 65k colours */
@@ -142,16 +139,20 @@
#define HW_SAMPR_CAPS SAMPR_CAP_44
-#define BATTERY_CAPACITY_DEFAULT 1100 /* default battery capacity */
-#define BATTERY_CAPACITY_MIN 500 /* min. capacity selectable */
-#define BATTERY_CAPACITY_MAX 2500 /* max. capacity selectable */
+#define BATTERY_CAPACITY_DEFAULT 1500 /* default battery capacity */
+#define BATTERY_CAPACITY_MIN 1000 /* min. capacity selectable */
+#define BATTERY_CAPACITY_MAX 2000 /* max. capacity selectable */
#define BATTERY_CAPACITY_INC 100 /* capacity increment */
#define BATTERY_TYPES_COUNT 1 /* only one type */
+/* define current usage levels */
+#define CURRENT_NORMAL 120 /* Measured */
+#define CURRENT_BACKLIGHT 80 /* Over 200 mA total measured when on */
+#define CURRENT_RECORD 0 /* no recording */
+
/* Hardware controlled charging with monitoring */
#define CONFIG_CHARGING CHARGING_MONITOR
-
/* Define this if you have a Texas Instruments TSC2100 touch screen */
#define HAVE_TSC2100
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 4f35927..e52356b 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -97,8 +97,15 @@ void lcd_set_mode(int mode);
#define LCD_MODE_RGB565 0x00000001
#define LCD_MODE_YUV 0x00000002
#define LCD_MODE_PAL256 0x00000004
+
+#if HAVE_LCD_MODES & LCD_MODE_PAL256
+ void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y,
+ int width, int height);
+ void lcd_pal256_update_pal(fb_data *palette);
+#endif
#endif
+
/* common functions */
extern void lcd_write_command(int byte);
extern void lcd_write_command_e(int cmd, int data);
diff --git a/firmware/target/arm/tms320dm320/app.lds b/firmware/target/arm/tms320dm320/app.lds
index 47ff239..4e17510 100644
--- a/firmware/target/arm/tms320dm320/app.lds
+++ b/firmware/target/arm/tms320dm320/app.lds
@@ -6,35 +6,30 @@ OUTPUT_FORMAT(elf32-littlearm)
OUTPUT_ARCH(arm)
STARTUP(target/arm/tms320dm320/crt0.o)
-#define PLUGINSIZE PLUGIN_BUFFER_SIZE
-#define CODECSIZE CODEC_SIZE
-
#ifdef DEBUG
#define STUBOFFSET 0x10000
#else
#define STUBOFFSET 0
#endif
-#define LCD_BUFFER_SIZE (LCD_WIDTH*LCD_HEIGHT*2)
-
-/* must be 16Kb (0x4000) aligned */
-#define TTB_SIZE (0x4000)
+#define LCD_FUDGE LCD_NATIVE_WIDTH%32
-#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE - CODECSIZE - LCD_BUFFER_SIZE - TTB_SIZE
+#define LCD_BUFFER_SIZE ((LCD_NATIVE_WIDTH+LCD_FUDGE)*LCD_NATIVE_HEIGHT*2)
-#define DRAMORIG 0x00900000 + STUBOFFSET
-#define IRAMORIG 0x00000000
-#define IRAMSIZE 0x4000
+/* must be 16Kb (0x4000) aligned */
+#define TTB_SIZE 0x4000
-/* End of the audio buffer, where the codec buffer starts */
-#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE)
+/* Give this 1 meg to allow it to align to the MMU boundary */
+#define LCD_TTB_AREA 0x100000
-/* Where the codec buffer ends, and the plugin buffer starts */
-#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
+#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET
-#define LCDBEGIN (ENDADDR + PLUGINSIZE)
+#define DRAMORIG 0x00900000 + STUBOFFSET
+#define IRAMORIG 0x00000000
+#define IRAMSIZE 0x4000
-#define TTBBEGIN (LCDBEGIN + LCD_BUFFER_SIZE)
+/* End of the audio buffer, where the codec buffer starts */
+#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_TTB_AREA)
MEMORY
{
@@ -144,22 +139,32 @@ SECTIONS
{
codecbuf = .;
_codecbuf = .;
- }
+ . += CODEC_SIZE;
+ } > DRAM
- .plugin ENDADDR (NOLOAD) :
+ .plugin (NOLOAD) :
{
_pluginbuf = .;
pluginbuf = .;
- }
+ . += PLUGIN_BUFFER_SIZE;
+ } > DRAM
- .lcdbuffer LCDBEGIN (NOLOAD) :
+ .ttbtable (NOLOAD) :
{
- _lcdbuf = .;
- }
+ . = ALIGN (0x4000);
+ _ttbstart = .;
+ . += TTB_SIZE;
+ } > DRAM
+
+ /* The LCD buffer should be at the end of memory to protect against
+ * overflowing something else when the YUV blitter is fudging the screen
+ * size.
+ */
- .ttbtable TTBBEGIN (NOLOAD) :
+ .lcdbuffer (NOLOAD) :
{
- _ttbstart = .;
- }
+ _lcdbuf = .;
+ . += LCD_BUFFER_SIZE;
+ } > DRAM
}
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
index 3fa8a7e..1334eea 100644
--- a/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
+++ b/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
@@ -112,6 +112,11 @@ void lcd_enable(bool state)
}
#endif
+/* Note this is expecting a screen size of 480x640 or 240x320, other screen
+ * sizes need to be considered for fudge factors
+ */
+#define LCD_FUDGE LCD_NATIVE_WIDTH%32
+
/* LCD init - based on code from ingenient-bsp/bootloader/board/dm320/splash.c
* and code by Catalin Patulea from the M:Robe 500i linux port
*/
@@ -122,21 +127,26 @@ void lcd_init_device(void)
/* Clear the Frame */
memset16(FRAME, 0x0000, LCD_WIDTH*LCD_HEIGHT);
+ lcd_sleep();
+
+ IO_OSD_OSDWINMD0&=~(0x0001);
+ IO_OSD_VIDWINMD&=~(0x0001);
+
/* Setup the LCD controller */
- IO_VID_ENC_VMOD=0x2015;
+ IO_VID_ENC_VMOD=0x2014;
IO_VID_ENC_VDCTL=0x2000;
IO_VID_ENC_VDPRO=0x0000;
IO_VID_ENC_SYNCTL=0x100E;
IO_VID_ENC_HSPLS=1; /* HSYNC pulse width */
IO_VID_ENC_VSPLS=1; /* VSYNC pulse width */
- /* These calculations support 640x480 and 320x240 */
- IO_VID_ENC_HINT=NATIVE_MAX_WIDTH+NATIVE_MAX_WIDTH/3;
- IO_VID_ENC_HSTART=NATIVE_MAX_WIDTH/6; /* Front porch */
- IO_VID_ENC_HVALID=NATIVE_MAX_WIDTH; /* Data valid */
- IO_VID_ENC_VINT=NATIVE_MAX_HEIGHT+7;
+ /* These calculations support 640x480 and 320x240 (based on OF) */
+ IO_VID_ENC_HINT=LCD_NATIVE_WIDTH+LCD_NATIVE_WIDTH/3;
+ IO_VID_ENC_HSTART=LCD_NATIVE_WIDTH/6; /* Front porch */
+ IO_VID_ENC_HVALID=LCD_NATIVE_WIDTH; /* Data valid */
+ IO_VID_ENC_VINT=LCD_NATIVE_HEIGHT+7;
IO_VID_ENC_VSTART=3;
- IO_VID_ENC_VVALID=NATIVE_MAX_HEIGHT;
+ IO_VID_ENC_VVALID=LCD_NATIVE_HEIGHT;
IO_VID_ENC_HSDLY=0x0000;
IO_VID_ENC_VSDLY=0x0000;
@@ -152,46 +162,88 @@ void lcd_init_device(void)
IO_VID_ENC_PWMP=0x0000;
IO_VID_ENC_PWMW=0x0000;
- IO_VID_ENC_DCLKCTL=0x0800;
IO_VID_ENC_DCLKPTN0=0x0001;
-
/* Setup the display */
IO_OSD_MODE=0x00ff;
- IO_OSD_VIDWINMD=0x0002;
- IO_OSD_OSDWINMD0=0x2001;
- IO_OSD_OSDWINMD1=0x0002;
+
IO_OSD_ATRMD=0x0000;
IO_OSD_RECTCUR=0x0000;
-
- IO_OSD_OSDWIN0OFST=(NATIVE_MAX_WIDTH*2) / 32;
+
+ IO_OSD_BASEPX=IO_VID_ENC_HSTART;
+ IO_OSD_BASEPY=IO_VID_ENC_VSTART;
addr = ((int)FRAME-CONFIG_SDRAM_START) / 32;
- IO_OSD_OSDWINADH=addr >> 16;
- IO_OSD_OSDWIN0ADL=addr & 0xFFFF;
+
+ /* Setup the OSD windows */
- IO_OSD_VIDWINADH=addr >> 16;
- IO_OSD_VIDWIN0ADL=addr & 0xFFFF;
+ /* Used for 565 RGB */
+ IO_OSD_OSDWINMD0=0x30C0;
- IO_OSD_BASEPX=IO_VID_ENC_HSTART;
- IO_OSD_BASEPY=IO_VID_ENC_VSTART;
+ IO_OSD_OSDWIN0OFST=LCD_NATIVE_WIDTH / 16;
+
+ IO_OSD_OSDWINADH=addr >> 16;
+ IO_OSD_OSDWIN0ADL=addr & 0xFFFF;
IO_OSD_OSDWIN0XP=0;
IO_OSD_OSDWIN0YP=0;
-
- IO_OSD_OSDWIN0XL=NATIVE_MAX_WIDTH;
- IO_OSD_OSDWIN0YL=NATIVE_MAX_HEIGHT;
+
+ /* read from OF */
+ IO_OSD_OSDWIN0XL=LCD_NATIVE_WIDTH;
+ IO_OSD_OSDWIN0YL=LCD_NATIVE_HEIGHT;
+
+ /* Unused */
+ IO_OSD_OSDWINMD1=0x10C0;
+
+#if LCD_NATIVE_WIDTH%32!=0
+ IO_OSD_OSDWIN1OFST=LCD_NATIVE_WIDTH / 32+1;
+#else
+ IO_OSD_OSDWIN1OFST=LCD_NATIVE_WIDTH / 32;
+#endif
+
+ IO_OSD_OSDWIN1ADL=addr & 0xFFFF;
+
+ IO_OSD_OSDWIN1XP=0;
+ IO_OSD_OSDWIN1YP=0;
+
+ IO_OSD_OSDWIN1XL=LCD_NATIVE_WIDTH;
+ IO_OSD_OSDWIN1YL=LCD_NATIVE_HEIGHT;
+
+ IO_OSD_VIDWINMD=0x0002;
+
+ /* This is a bit messy, the LCD transfers appear to happen in chunks of 32
+ * pixels. (based on OF)
+ */
+#if LCD_NATIVE_WIDTH%32!=0
+ IO_OSD_VIDWIN0OFST=LCD_NATIVE_WIDTH / 32+1;
+#else
+ IO_OSD_VIDWIN0OFST=LCD_NATIVE_WIDTH / 32;
+#endif
+
+ IO_OSD_VIDWINADH=addr >> 16;
+ IO_OSD_VIDWIN0ADL=addr & 0xFFFF;
+
+ IO_OSD_VIDWIN0XP=0;
+ IO_OSD_VIDWIN0YP=0;
+
+ IO_OSD_VIDWIN0XL=LCD_NATIVE_WIDTH;
+ IO_OSD_VIDWIN0YL=LCD_NATIVE_HEIGHT;
/* Set pin 36 and 35 (LCD POWER and LCD RESOLUTION) to an output */
IO_GIO_DIR2&=!(3<<3);
-#if NATIVE_MAX_HEIGHT > 320
+#if LCD_NATIVE_HEIGHT > 320
/* Set LCD resolution to VGA */
IO_GIO_BITSET2=1<<3;
#else
/* Set LCD resolution to QVGA */
IO_GIO_BITCLR2=1<<3;
#endif
+
+ IO_OSD_OSDWINMD0|=0x01;
+ IO_VID_ENC_VMOD|=0x01;
+
+ lcd_enable(true);
}
/* Update a fraction of the display. */
@@ -216,9 +268,10 @@ void lcd_update_rect(int x, int y, int width, int height)
if (height <= 0)
return; /* nothing left to do */
+ src = &lcd_framebuffer[y][x];
+
#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
dst = (fb_data *)FRAME + LCD_WIDTH*y + x;
- src = &lcd_framebuffer[y][x];
/* Copy part of the Rockbox framebuffer to the second framebuffer */
if (width < LCD_WIDTH)
@@ -232,21 +285,23 @@ void lcd_update_rect(int x, int y, int width, int height)
lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1);
}
#else
- src = &lcd_framebuffer[y][x];
-
- register int xc, yc;
- register fb_data *start=FRAME + LCD_HEIGHT*(LCD_WIDTH-x-1) + y + 1;
+ dst=FRAME + (LCD_NATIVE_WIDTH*(LCD_NATIVE_HEIGHT-1))
+ - LCD_NATIVE_WIDTH*x + y ;
- for(yc=0;yc<height;yc++)
+ do
{
- dst=start+yc;
- for(xc=0; xc<width; xc++)
+ register int c_width=width;
+ register fb_data *c_dst=dst;
+ do
{
- *dst=*src++;
- dst-=LCD_HEIGHT;
+ *c_dst=*src++;
+ c_dst-=LCD_NATIVE_WIDTH;
}
- src+=x;
+ while(--c_width);
+ src+=LCD_WIDTH-width-x;
+ dst++;
}
+ while(--height);
#endif
}
@@ -271,20 +326,94 @@ void lcd_set_mode(int mode)
if(mode==LCD_MODE_YUV)
{
/* Turn off the RGB buffer and enable the YUV buffer */
- IO_OSD_OSDWINMD0&=~(0x01);
- IO_OSD_VIDWINMD|=0x01;
- memset16(FRAME, 0x0080, LCD_WIDTH*LCD_HEIGHT);
+ IO_OSD_OSDWINMD0 &=~(0x01);
+ IO_OSD_VIDWINMD |=0x01;
+ memset16(FRAME, 0x0080, LCD_NATIVE_HEIGHT*(LCD_NATIVE_WIDTH+LCD_FUDGE));
}
else if(mode==LCD_MODE_RGB565)
{
- /* Turn on the RGB window and the YUV window off (This should probably be
- * made into a function).
- */
- IO_OSD_OSDWINMD0|=0x01;
- IO_OSD_VIDWINMD&=~(0x01);
+ /* Turn on the RGB window, set it to 16 bit and turn YUV window off */
+ IO_OSD_VIDWINMD &=~(0x01);
+ IO_OSD_OSDWIN0OFST=LCD_NATIVE_WIDTH / 16;
+ IO_OSD_OSDWINMD0 |=(1<<13)|0x01;
+ lcd_clear_display();
}
else if(mode==LCD_MODE_PAL256)
{
+#if LCD_NATIVE_WIDTH%32!=0
+ IO_OSD_OSDWIN0OFST=LCD_NATIVE_WIDTH / 32+1;
+#else
+ IO_OSD_OSDWIN0OFST=LCD_NATIVE_WIDTH / 32;
+#endif
+
+ IO_OSD_VIDWINMD &=~(0x01);
+ IO_OSD_OSDWINMD0 &=~(1<<13);
+ IO_OSD_OSDWINMD0 |=0x01;
+ }
+}
+#endif
+
+#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
+void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y,
+ int width, int height)
+{
+#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
+ char *dst=(char *)FRAME+x+y*(LCD_NATIVE_WIDTH+LCD_FUDGE);
+
+ src=src+src_x+src_y*LCD_NATIVE_WIDTH;
+ do
+ {
+ memcpy ( dst, src, width);
+
+ /* The LCD uses the top 1/4 of the screen when in palette mode */
+ dst=dst+width+(LCD_NATIVE_WIDTH-x-width)+LCD_FUDGE;
+ src+=width;
+ }
+ while(--height);
+#else
+ char *dst=(char *)FRAME
+ + (LCD_NATIVE_WIDTH+LCD_FUDGE)*(LCD_NATIVE_HEIGHT-1)
+ - (LCD_NATIVE_WIDTH+LCD_FUDGE)*x + y;
+
+ src=src+src_x+src_y*LCD_WIDTH;
+ do
+ {
+ register char *c_dst=dst;
+ register int c_width=width;
+ do
+ {
+ *c_dst=*src++;
+ /* The LCD uses the top 1/4 of the screen when in palette mode */
+ c_dst=c_dst-(LCD_NATIVE_WIDTH+LCD_FUDGE);
+ } while (--c_width);
+ dst++;
+ src=src+(LCD_WIDTH-width-x);
+ }
+ while(--height);
+#endif
+}
+
+void lcd_pal256_update_pal(fb_data *palette)
+{
+ unsigned char i;
+ for(i=0; i< 255; i++)
+ {
+ int y, cb, cr;
+ unsigned char r=RGB_UNPACK_RED_LCD(palette[i])<<3;
+ unsigned char g=RGB_UNPACK_GREEN_LCD(palette[i])<<2;
+ unsigned char b=RGB_UNPACK_BLUE_LCD(palette[i])<<3;
+
+ y = ((77 * r + 150 * g + 29 * b) >> 8); cb = ((-43 * r - 85 * g + 128 * b) >> 8) + 128;
+ cr = ((128 * r - 107 * g - 21 * b) >> 8) + 128;
+
+ while(IO_OSD_MISCCTL&0x08)
+ {};
+
+ /* Write in y and cb */
+ IO_OSD_CLUTRAMYCB= ((unsigned char)y << 8) | (unsigned char)cb;
+
+ /* Write in the index and cr */
+ IO_OSD_CLUTRAMCR=((unsigned char)cr << 8) | i;
}
}
#endif
@@ -308,14 +437,32 @@ void lcd_blit_yuv(unsigned char * const src[3],
if (!lcd_on)
return;
- /* y has to be at multiple of 2 or else it will mess up the HW (interleaving) */
+ /* y has to be at multiple of 2 or else it will mess up the HW
+ * (interleaving)
+ */
y &= ~1;
+ if(y<0 || y>LCD_NATIVE_HEIGHT || x<0 || x>LCD_NATIVE_WIDTH
+ || height<0 || width <0)
+ {
+ return;
+ }
+
+ if(y+height>LCD_NATIVE_WIDTH)
+ {
+ height=LCD_NATIVE_WIDTH-y;
+ }
+ if(x+width>LCD_NATIVE_HEIGHT)
+ {
+ width=LCD_NATIVE_HEIGHT-x;
+ }
+
/* Sorry, but width and height must be >= 2 or else */
width &= ~1;
height>>=1;
- fb_data *dst = (fb_data*)FRAME + LCD_WIDTH*LCD_HEIGHT - x * LCD_WIDTH + y;
+ fb_data * dst = FRAME + ((LCD_NATIVE_WIDTH+LCD_FUDGE)*(LCD_NATIVE_HEIGHT-1))
+ - (LCD_NATIVE_WIDTH+LCD_FUDGE)*x + y ;
z = stride*src_y;
yuv_src[0] = src[0] + z + src_x;
@@ -337,11 +484,11 @@ void lcd_blit_yuv(unsigned char * const src[3],
/* This needs to be done in a block of 4 pixels */
*c_dst=*c_yuv_src[0]<<8 | *c_yuv_src[1];
*(c_dst+1)=*(c_yuv_src[0]+stride)<<8 | *c_yuv_src[2];
- c_dst-=LCD_WIDTH;
+ c_dst-=(LCD_NATIVE_WIDTH+LCD_FUDGE);
c_yuv_src[0]++;
*c_dst=*c_yuv_src[0]<<8 | *c_yuv_src[1];
*(c_dst+1)=*(c_yuv_src[0]+stride)<<8 | *c_yuv_src[2];
- c_dst-=LCD_WIDTH;
+ c_dst-=(LCD_NATIVE_WIDTH+LCD_FUDGE);
c_yuv_src[0]++;
c_yuv_src[1]++;