M:Robe 500: More LCD initialization, QVGA (vs. VGA) is now enabled by default for performance, 256 color palette mode added, include some linker cleanups and reorganization. Doom and MPEGPlayer now run reaonably well.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20664 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Karl Kurbjun 2009-04-09 04:22:14 +00:00
parent 49fcfe81b8
commit 93fccc763b
8 changed files with 338 additions and 138 deletions

View file

@ -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)

View file

@ -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 */

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -97,7 +97,14 @@ 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);

View file

@ -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)
#define LCD_FUDGE LCD_NATIVE_WIDTH%32
#define LCD_BUFFER_SIZE ((LCD_NATIVE_WIDTH+LCD_FUDGE)*LCD_NATIVE_HEIGHT*2)
/* must be 16Kb (0x4000) aligned */
#define TTB_SIZE (0x4000)
#define TTB_SIZE 0x4000
#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE - CODECSIZE - LCD_BUFFER_SIZE - TTB_SIZE
/* Give this 1 meg to allow it to align to the MMU boundary */
#define LCD_TTB_AREA 0x100000
#define DRAMORIG 0x00900000 + STUBOFFSET
#define IRAMORIG 0x00000000
#define IRAMSIZE 0x4000
#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET
#define DRAMORIG 0x00900000 + STUBOFFSET
#define IRAMORIG 0x00000000
#define IRAMSIZE 0x4000
/* End of the audio buffer, where the codec buffer starts */
#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE)
/* Where the codec buffer ends, and the plugin buffer starts */
#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
#define LCDBEGIN (ENDADDR + PLUGINSIZE)
#define TTBBEGIN (LCDBEGIN + LCD_BUFFER_SIZE)
#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) :
{
. = 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.
*/
.lcdbuffer (NOLOAD) :
{
_lcdbuf = .;
}
.ttbtable TTBBEGIN (NOLOAD) :
{
_ttbstart = .;
}
. += LCD_BUFFER_SIZE;
} > DRAM
}

View file

@ -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;
addr = ((int)FRAME-CONFIG_SDRAM_START) / 32;
IO_OSD_OSDWINADH=addr >> 16;
IO_OSD_OSDWIN0ADL=addr & 0xFFFF;
IO_OSD_VIDWINADH=addr >> 16;
IO_OSD_VIDWIN0ADL=addr & 0xFFFF;
IO_OSD_BASEPX=IO_VID_ENC_HSTART;
IO_OSD_BASEPY=IO_VID_ENC_VSTART;
addr = ((int)FRAME-CONFIG_SDRAM_START) / 32;
/* Setup the OSD windows */
/* Used for 565 RGB */
IO_OSD_OSDWINMD0=0x30C0;
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]++;