summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorKarl Kurbjun <kkurbjun@gmail.com>2009-04-09 04:22:14 +0000
committerKarl Kurbjun <kkurbjun@gmail.com>2009-04-09 04:22:14 +0000
commit93fccc763b97323cb3112bf9afee819cd03ba195 (patch)
tree8b3da3ecd807da715478fe4cc1697fcffea1bd67 /firmware
parent49fcfe81b861f866c4e9e16e272f33654a1be450 (diff)
downloadrockbox-93fccc763b97323cb3112bf9afee819cd03ba195.tar.gz
rockbox-93fccc763b97323cb3112bf9afee819cd03ba195.zip
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
Diffstat (limited to 'firmware')
-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
4 files changed, 251 insertions, 91 deletions
diff --git a/firmware/export/config-mrobe500.h b/firmware/export/config-mrobe500.h
index fafea48a94..90bbefe329 100644
--- a/firmware/export/config-mrobe500.h
+++ b/firmware/export/config-mrobe500.h
@@ -59,24 +59,21 @@
59/* LCD dimensions */ 59/* LCD dimensions */
60#define CONFIG_LCD LCD_MROBE500 60#define CONFIG_LCD LCD_MROBE500
61 61
62/* choose the lcd orientation. both work */ 62#if 0
63/* #define CONFIG_ORIENTATION SCREEN_PORTRAIT */ 63#define LCD_NATIVE_WIDTH 480
64#define CONFIG_ORIENTATION SCREEN_PORTRAIT 64#define LCD_NATIVE_HEIGHT 640
65
66#if 1
67#define NATIVE_MAX_WIDTH 480
68#define NATIVE_MAX_HEIGHT 640
69#else 65#else
70#define NATIVE_MAX_WIDTH 240 66#define LCD_NATIVE_WIDTH 240
71#define NATIVE_MAX_HEIGHT 320 67#define LCD_NATIVE_HEIGHT 320
72#endif 68#endif
73 69
74#if CONFIG_ORIENTATION == SCREEN_PORTRAIT 70/* choose the lcd orientation. CONFIG_ORIENTATION defined in config.h */
75#define LCD_WIDTH NATIVE_MAX_WIDTH 71#if 0
76#define LCD_HEIGHT NATIVE_MAX_HEIGHT 72#define LCD_WIDTH LCD_NATIVE_WIDTH
73#define LCD_HEIGHT LCD_NATIVE_HEIGHT
77#else 74#else
78#define LCD_WIDTH NATIVE_MAX_HEIGHT 75#define LCD_WIDTH LCD_NATIVE_HEIGHT
79#define LCD_HEIGHT NATIVE_MAX_WIDTH 76#define LCD_HEIGHT LCD_NATIVE_WIDTH
80#endif 77#endif
81 78
82#define LCD_DEPTH 16 /* 65k colours */ 79#define LCD_DEPTH 16 /* 65k colours */
@@ -142,16 +139,20 @@
142 139
143#define HW_SAMPR_CAPS SAMPR_CAP_44 140#define HW_SAMPR_CAPS SAMPR_CAP_44
144 141
145#define BATTERY_CAPACITY_DEFAULT 1100 /* default battery capacity */ 142#define BATTERY_CAPACITY_DEFAULT 1500 /* default battery capacity */
146#define BATTERY_CAPACITY_MIN 500 /* min. capacity selectable */ 143#define BATTERY_CAPACITY_MIN 1000 /* min. capacity selectable */
147#define BATTERY_CAPACITY_MAX 2500 /* max. capacity selectable */ 144#define BATTERY_CAPACITY_MAX 2000 /* max. capacity selectable */
148#define BATTERY_CAPACITY_INC 100 /* capacity increment */ 145#define BATTERY_CAPACITY_INC 100 /* capacity increment */
149#define BATTERY_TYPES_COUNT 1 /* only one type */ 146#define BATTERY_TYPES_COUNT 1 /* only one type */
150 147
148/* define current usage levels */
149#define CURRENT_NORMAL 120 /* Measured */
150#define CURRENT_BACKLIGHT 80 /* Over 200 mA total measured when on */
151#define CURRENT_RECORD 0 /* no recording */
152
151/* Hardware controlled charging with monitoring */ 153/* Hardware controlled charging with monitoring */
152#define CONFIG_CHARGING CHARGING_MONITOR 154#define CONFIG_CHARGING CHARGING_MONITOR
153 155
154
155/* Define this if you have a Texas Instruments TSC2100 touch screen */ 156/* Define this if you have a Texas Instruments TSC2100 touch screen */
156#define HAVE_TSC2100 157#define HAVE_TSC2100
157 158
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 4f35927353..e52356b8bf 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -97,8 +97,15 @@ void lcd_set_mode(int mode);
97#define LCD_MODE_RGB565 0x00000001 97#define LCD_MODE_RGB565 0x00000001
98#define LCD_MODE_YUV 0x00000002 98#define LCD_MODE_YUV 0x00000002
99#define LCD_MODE_PAL256 0x00000004 99#define LCD_MODE_PAL256 0x00000004
100
101#if HAVE_LCD_MODES & LCD_MODE_PAL256
102 void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y,
103 int width, int height);
104 void lcd_pal256_update_pal(fb_data *palette);
105#endif
100#endif 106#endif
101 107
108
102/* common functions */ 109/* common functions */
103extern void lcd_write_command(int byte); 110extern void lcd_write_command(int byte);
104extern void lcd_write_command_e(int cmd, int data); 111extern 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 47ff239a1a..4e175101a9 100644
--- a/firmware/target/arm/tms320dm320/app.lds
+++ b/firmware/target/arm/tms320dm320/app.lds
@@ -6,35 +6,30 @@ OUTPUT_FORMAT(elf32-littlearm)
6OUTPUT_ARCH(arm) 6OUTPUT_ARCH(arm)
7STARTUP(target/arm/tms320dm320/crt0.o) 7STARTUP(target/arm/tms320dm320/crt0.o)
8 8
9#define PLUGINSIZE PLUGIN_BUFFER_SIZE
10#define CODECSIZE CODEC_SIZE
11
12#ifdef DEBUG 9#ifdef DEBUG
13#define STUBOFFSET 0x10000 10#define STUBOFFSET 0x10000
14#else 11#else
15#define STUBOFFSET 0 12#define STUBOFFSET 0
16#endif 13#endif
17 14
18#define LCD_BUFFER_SIZE (LCD_WIDTH*LCD_HEIGHT*2) 15#define LCD_FUDGE LCD_NATIVE_WIDTH%32
19
20/* must be 16Kb (0x4000) aligned */
21#define TTB_SIZE (0x4000)
22 16
23#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE - CODECSIZE - LCD_BUFFER_SIZE - TTB_SIZE 17#define LCD_BUFFER_SIZE ((LCD_NATIVE_WIDTH+LCD_FUDGE)*LCD_NATIVE_HEIGHT*2)
24 18
25#define DRAMORIG 0x00900000 + STUBOFFSET 19/* must be 16Kb (0x4000) aligned */
26#define IRAMORIG 0x00000000 20#define TTB_SIZE 0x4000
27#define IRAMSIZE 0x4000
28 21
29/* End of the audio buffer, where the codec buffer starts */ 22/* Give this 1 meg to allow it to align to the MMU boundary */
30#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE) 23#define LCD_TTB_AREA 0x100000
31 24
32/* Where the codec buffer ends, and the plugin buffer starts */ 25#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET
33#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
34 26
35#define LCDBEGIN (ENDADDR + PLUGINSIZE) 27#define DRAMORIG 0x00900000 + STUBOFFSET
28#define IRAMORIG 0x00000000
29#define IRAMSIZE 0x4000
36 30
37#define TTBBEGIN (LCDBEGIN + LCD_BUFFER_SIZE) 31/* End of the audio buffer, where the codec buffer starts */
32#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_TTB_AREA)
38 33
39MEMORY 34MEMORY
40{ 35{
@@ -144,22 +139,32 @@ SECTIONS
144 { 139 {
145 codecbuf = .; 140 codecbuf = .;
146 _codecbuf = .; 141 _codecbuf = .;
147 } 142 . += CODEC_SIZE;
143 } > DRAM
148 144
149 .plugin ENDADDR (NOLOAD) : 145 .plugin (NOLOAD) :
150 { 146 {
151 _pluginbuf = .; 147 _pluginbuf = .;
152 pluginbuf = .; 148 pluginbuf = .;
153 } 149 . += PLUGIN_BUFFER_SIZE;
150 } > DRAM
154 151
155 .lcdbuffer LCDBEGIN (NOLOAD) : 152 .ttbtable (NOLOAD) :
156 { 153 {
157 _lcdbuf = .; 154 . = ALIGN (0x4000);
158 } 155 _ttbstart = .;
156 . += TTB_SIZE;
157 } > DRAM
158
159 /* The LCD buffer should be at the end of memory to protect against
160 * overflowing something else when the YUV blitter is fudging the screen
161 * size.
162 */
159 163
160 .ttbtable TTBBEGIN (NOLOAD) : 164 .lcdbuffer (NOLOAD) :
161 { 165 {
162 _ttbstart = .; 166 _lcdbuf = .;
163 } 167 . += LCD_BUFFER_SIZE;
168 } > DRAM
164} 169}
165 170
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
index 3fa8a7e6c1..1334eeaf8d 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)
112} 112}
113#endif 113#endif
114 114
115/* Note this is expecting a screen size of 480x640 or 240x320, other screen
116 * sizes need to be considered for fudge factors
117 */
118#define LCD_FUDGE LCD_NATIVE_WIDTH%32
119
115/* LCD init - based on code from ingenient-bsp/bootloader/board/dm320/splash.c 120/* LCD init - based on code from ingenient-bsp/bootloader/board/dm320/splash.c
116 * and code by Catalin Patulea from the M:Robe 500i linux port 121 * and code by Catalin Patulea from the M:Robe 500i linux port
117 */ 122 */
@@ -122,21 +127,26 @@ void lcd_init_device(void)
122 /* Clear the Frame */ 127 /* Clear the Frame */
123 memset16(FRAME, 0x0000, LCD_WIDTH*LCD_HEIGHT); 128 memset16(FRAME, 0x0000, LCD_WIDTH*LCD_HEIGHT);
124 129
130 lcd_sleep();
131
132 IO_OSD_OSDWINMD0&=~(0x0001);
133 IO_OSD_VIDWINMD&=~(0x0001);
134
125 /* Setup the LCD controller */ 135 /* Setup the LCD controller */
126 IO_VID_ENC_VMOD=0x2015; 136 IO_VID_ENC_VMOD=0x2014;
127 IO_VID_ENC_VDCTL=0x2000; 137 IO_VID_ENC_VDCTL=0x2000;
128 IO_VID_ENC_VDPRO=0x0000; 138 IO_VID_ENC_VDPRO=0x0000;
129 IO_VID_ENC_SYNCTL=0x100E; 139 IO_VID_ENC_SYNCTL=0x100E;
130 IO_VID_ENC_HSPLS=1; /* HSYNC pulse width */ 140 IO_VID_ENC_HSPLS=1; /* HSYNC pulse width */
131 IO_VID_ENC_VSPLS=1; /* VSYNC pulse width */ 141 IO_VID_ENC_VSPLS=1; /* VSYNC pulse width */
132 142
133 /* These calculations support 640x480 and 320x240 */ 143 /* These calculations support 640x480 and 320x240 (based on OF) */
134 IO_VID_ENC_HINT=NATIVE_MAX_WIDTH+NATIVE_MAX_WIDTH/3; 144 IO_VID_ENC_HINT=LCD_NATIVE_WIDTH+LCD_NATIVE_WIDTH/3;
135 IO_VID_ENC_HSTART=NATIVE_MAX_WIDTH/6; /* Front porch */ 145 IO_VID_ENC_HSTART=LCD_NATIVE_WIDTH/6; /* Front porch */
136 IO_VID_ENC_HVALID=NATIVE_MAX_WIDTH; /* Data valid */ 146 IO_VID_ENC_HVALID=LCD_NATIVE_WIDTH; /* Data valid */
137 IO_VID_ENC_VINT=NATIVE_MAX_HEIGHT+7; 147 IO_VID_ENC_VINT=LCD_NATIVE_HEIGHT+7;
138 IO_VID_ENC_VSTART=3; 148 IO_VID_ENC_VSTART=3;
139 IO_VID_ENC_VVALID=NATIVE_MAX_HEIGHT; 149 IO_VID_ENC_VVALID=LCD_NATIVE_HEIGHT;
140 150
141 IO_VID_ENC_HSDLY=0x0000; 151 IO_VID_ENC_HSDLY=0x0000;
142 IO_VID_ENC_VSDLY=0x0000; 152 IO_VID_ENC_VSDLY=0x0000;
@@ -152,46 +162,88 @@ void lcd_init_device(void)
152 IO_VID_ENC_PWMP=0x0000; 162 IO_VID_ENC_PWMP=0x0000;
153 IO_VID_ENC_PWMW=0x0000; 163 IO_VID_ENC_PWMW=0x0000;
154 164
155 IO_VID_ENC_DCLKCTL=0x0800;
156 IO_VID_ENC_DCLKPTN0=0x0001; 165 IO_VID_ENC_DCLKPTN0=0x0001;
157 166
158
159 /* Setup the display */ 167 /* Setup the display */
160 IO_OSD_MODE=0x00ff; 168 IO_OSD_MODE=0x00ff;
161 IO_OSD_VIDWINMD=0x0002; 169
162 IO_OSD_OSDWINMD0=0x2001;
163 IO_OSD_OSDWINMD1=0x0002;
164 IO_OSD_ATRMD=0x0000; 170 IO_OSD_ATRMD=0x0000;
165 IO_OSD_RECTCUR=0x0000; 171 IO_OSD_RECTCUR=0x0000;
166 172
167 IO_OSD_OSDWIN0OFST=(NATIVE_MAX_WIDTH*2) / 32; 173 IO_OSD_BASEPX=IO_VID_ENC_HSTART;
174 IO_OSD_BASEPY=IO_VID_ENC_VSTART;
168 175
169 addr = ((int)FRAME-CONFIG_SDRAM_START) / 32; 176 addr = ((int)FRAME-CONFIG_SDRAM_START) / 32;
170 IO_OSD_OSDWINADH=addr >> 16; 177
171 IO_OSD_OSDWIN0ADL=addr & 0xFFFF; 178 /* Setup the OSD windows */
172 179
173 IO_OSD_VIDWINADH=addr >> 16; 180 /* Used for 565 RGB */
174 IO_OSD_VIDWIN0ADL=addr & 0xFFFF; 181 IO_OSD_OSDWINMD0=0x30C0;
175 182
176 IO_OSD_BASEPX=IO_VID_ENC_HSTART; 183 IO_OSD_OSDWIN0OFST=LCD_NATIVE_WIDTH / 16;
177 IO_OSD_BASEPY=IO_VID_ENC_VSTART; 184
185 IO_OSD_OSDWINADH=addr >> 16;
186 IO_OSD_OSDWIN0ADL=addr & 0xFFFF;
178 187
179 IO_OSD_OSDWIN0XP=0; 188 IO_OSD_OSDWIN0XP=0;
180 IO_OSD_OSDWIN0YP=0; 189 IO_OSD_OSDWIN0YP=0;
181 190
182 IO_OSD_OSDWIN0XL=NATIVE_MAX_WIDTH; 191 /* read from OF */
183 IO_OSD_OSDWIN0YL=NATIVE_MAX_HEIGHT; 192 IO_OSD_OSDWIN0XL=LCD_NATIVE_WIDTH;
193 IO_OSD_OSDWIN0YL=LCD_NATIVE_HEIGHT;
194
195 /* Unused */
196 IO_OSD_OSDWINMD1=0x10C0;
197
198#if LCD_NATIVE_WIDTH%32!=0
199 IO_OSD_OSDWIN1OFST=LCD_NATIVE_WIDTH / 32+1;
200#else
201 IO_OSD_OSDWIN1OFST=LCD_NATIVE_WIDTH / 32;
202#endif
203
204 IO_OSD_OSDWIN1ADL=addr & 0xFFFF;
205
206 IO_OSD_OSDWIN1XP=0;
207 IO_OSD_OSDWIN1YP=0;
208
209 IO_OSD_OSDWIN1XL=LCD_NATIVE_WIDTH;
210 IO_OSD_OSDWIN1YL=LCD_NATIVE_HEIGHT;
211
212 IO_OSD_VIDWINMD=0x0002;
213
214 /* This is a bit messy, the LCD transfers appear to happen in chunks of 32
215 * pixels. (based on OF)
216 */
217#if LCD_NATIVE_WIDTH%32!=0
218 IO_OSD_VIDWIN0OFST=LCD_NATIVE_WIDTH / 32+1;
219#else
220 IO_OSD_VIDWIN0OFST=LCD_NATIVE_WIDTH / 32;
221#endif
222
223 IO_OSD_VIDWINADH=addr >> 16;
224 IO_OSD_VIDWIN0ADL=addr & 0xFFFF;
225
226 IO_OSD_VIDWIN0XP=0;
227 IO_OSD_VIDWIN0YP=0;
228
229 IO_OSD_VIDWIN0XL=LCD_NATIVE_WIDTH;
230 IO_OSD_VIDWIN0YL=LCD_NATIVE_HEIGHT;
184 231
185 /* Set pin 36 and 35 (LCD POWER and LCD RESOLUTION) to an output */ 232 /* Set pin 36 and 35 (LCD POWER and LCD RESOLUTION) to an output */
186 IO_GIO_DIR2&=!(3<<3); 233 IO_GIO_DIR2&=!(3<<3);
187 234
188#if NATIVE_MAX_HEIGHT > 320 235#if LCD_NATIVE_HEIGHT > 320
189 /* Set LCD resolution to VGA */ 236 /* Set LCD resolution to VGA */
190 IO_GIO_BITSET2=1<<3; 237 IO_GIO_BITSET2=1<<3;
191#else 238#else
192 /* Set LCD resolution to QVGA */ 239 /* Set LCD resolution to QVGA */
193 IO_GIO_BITCLR2=1<<3; 240 IO_GIO_BITCLR2=1<<3;
194#endif 241#endif
242
243 IO_OSD_OSDWINMD0|=0x01;
244 IO_VID_ENC_VMOD|=0x01;
245
246 lcd_enable(true);
195} 247}
196 248
197/* Update a fraction of the display. */ 249/* Update a fraction of the display. */
@@ -216,9 +268,10 @@ void lcd_update_rect(int x, int y, int width, int height)
216 if (height <= 0) 268 if (height <= 0)
217 return; /* nothing left to do */ 269 return; /* nothing left to do */
218 270
271 src = &lcd_framebuffer[y][x];
272
219#if CONFIG_ORIENTATION == SCREEN_PORTRAIT 273#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
220 dst = (fb_data *)FRAME + LCD_WIDTH*y + x; 274 dst = (fb_data *)FRAME + LCD_WIDTH*y + x;
221 src = &lcd_framebuffer[y][x];
222 275
223 /* Copy part of the Rockbox framebuffer to the second framebuffer */ 276 /* Copy part of the Rockbox framebuffer to the second framebuffer */
224 if (width < LCD_WIDTH) 277 if (width < LCD_WIDTH)
@@ -232,21 +285,23 @@ void lcd_update_rect(int x, int y, int width, int height)
232 lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); 285 lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1);
233 } 286 }
234#else 287#else
235 src = &lcd_framebuffer[y][x]; 288 dst=FRAME + (LCD_NATIVE_WIDTH*(LCD_NATIVE_HEIGHT-1))
236 289 - LCD_NATIVE_WIDTH*x + y ;
237 register int xc, yc;
238 register fb_data *start=FRAME + LCD_HEIGHT*(LCD_WIDTH-x-1) + y + 1;
239 290
240 for(yc=0;yc<height;yc++) 291 do
241 { 292 {
242 dst=start+yc; 293 register int c_width=width;
243 for(xc=0; xc<width; xc++) 294 register fb_data *c_dst=dst;
295 do
244 { 296 {
245 *dst=*src++; 297 *c_dst=*src++;
246 dst-=LCD_HEIGHT; 298 c_dst-=LCD_NATIVE_WIDTH;
247 } 299 }
248 src+=x; 300 while(--c_width);
301 src+=LCD_WIDTH-width-x;
302 dst++;
249 } 303 }
304 while(--height);
250#endif 305#endif
251} 306}
252 307
@@ -271,20 +326,94 @@ void lcd_set_mode(int mode)
271 if(mode==LCD_MODE_YUV) 326 if(mode==LCD_MODE_YUV)
272 { 327 {
273 /* Turn off the RGB buffer and enable the YUV buffer */ 328 /* Turn off the RGB buffer and enable the YUV buffer */
274 IO_OSD_OSDWINMD0&=~(0x01); 329 IO_OSD_OSDWINMD0 &=~(0x01);
275 IO_OSD_VIDWINMD|=0x01; 330 IO_OSD_VIDWINMD |=0x01;
276 memset16(FRAME, 0x0080, LCD_WIDTH*LCD_HEIGHT); 331 memset16(FRAME, 0x0080, LCD_NATIVE_HEIGHT*(LCD_NATIVE_WIDTH+LCD_FUDGE));
277 } 332 }
278 else if(mode==LCD_MODE_RGB565) 333 else if(mode==LCD_MODE_RGB565)
279 { 334 {
280 /* Turn on the RGB window and the YUV window off (This should probably be 335 /* Turn on the RGB window, set it to 16 bit and turn YUV window off */
281 * made into a function). 336 IO_OSD_VIDWINMD &=~(0x01);
282 */ 337 IO_OSD_OSDWIN0OFST=LCD_NATIVE_WIDTH / 16;
283 IO_OSD_OSDWINMD0|=0x01; 338 IO_OSD_OSDWINMD0 |=(1<<13)|0x01;
284 IO_OSD_VIDWINMD&=~(0x01); 339 lcd_clear_display();
285 } 340 }
286 else if(mode==LCD_MODE_PAL256) 341 else if(mode==LCD_MODE_PAL256)
287 { 342 {
343#if LCD_NATIVE_WIDTH%32!=0
344 IO_OSD_OSDWIN0OFST=LCD_NATIVE_WIDTH / 32+1;
345#else
346 IO_OSD_OSDWIN0OFST=LCD_NATIVE_WIDTH / 32;
347#endif
348
349 IO_OSD_VIDWINMD &=~(0x01);
350 IO_OSD_OSDWINMD0 &=~(1<<13);
351 IO_OSD_OSDWINMD0 |=0x01;
352 }
353}
354#endif
355
356#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
357void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y,
358 int width, int height)
359{
360#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
361 char *dst=(char *)FRAME+x+y*(LCD_NATIVE_WIDTH+LCD_FUDGE);
362
363 src=src+src_x+src_y*LCD_NATIVE_WIDTH;
364 do
365 {
366 memcpy ( dst, src, width);
367
368 /* The LCD uses the top 1/4 of the screen when in palette mode */
369 dst=dst+width+(LCD_NATIVE_WIDTH-x-width)+LCD_FUDGE;
370 src+=width;
371 }
372 while(--height);
373#else
374 char *dst=(char *)FRAME
375 + (LCD_NATIVE_WIDTH+LCD_FUDGE)*(LCD_NATIVE_HEIGHT-1)
376 - (LCD_NATIVE_WIDTH+LCD_FUDGE)*x + y;
377
378 src=src+src_x+src_y*LCD_WIDTH;
379 do
380 {
381 register char *c_dst=dst;
382 register int c_width=width;
383 do
384 {
385 *c_dst=*src++;
386 /* The LCD uses the top 1/4 of the screen when in palette mode */
387 c_dst=c_dst-(LCD_NATIVE_WIDTH+LCD_FUDGE);
388 } while (--c_width);
389 dst++;
390 src=src+(LCD_WIDTH-width-x);
391 }
392 while(--height);
393#endif
394}
395
396void lcd_pal256_update_pal(fb_data *palette)
397{
398 unsigned char i;
399 for(i=0; i< 255; i++)
400 {
401 int y, cb, cr;
402 unsigned char r=RGB_UNPACK_RED_LCD(palette[i])<<3;
403 unsigned char g=RGB_UNPACK_GREEN_LCD(palette[i])<<2;
404 unsigned char b=RGB_UNPACK_BLUE_LCD(palette[i])<<3;
405
406 y = ((77 * r + 150 * g + 29 * b) >> 8); cb = ((-43 * r - 85 * g + 128 * b) >> 8) + 128;
407 cr = ((128 * r - 107 * g - 21 * b) >> 8) + 128;
408
409 while(IO_OSD_MISCCTL&0x08)
410 {};
411
412 /* Write in y and cb */
413 IO_OSD_CLUTRAMYCB= ((unsigned char)y << 8) | (unsigned char)cb;
414
415 /* Write in the index and cr */
416 IO_OSD_CLUTRAMCR=((unsigned char)cr << 8) | i;
288 } 417 }
289} 418}
290#endif 419#endif
@@ -308,14 +437,32 @@ void lcd_blit_yuv(unsigned char * const src[3],
308 if (!lcd_on) 437 if (!lcd_on)
309 return; 438 return;
310 439
311 /* y has to be at multiple of 2 or else it will mess up the HW (interleaving) */ 440 /* y has to be at multiple of 2 or else it will mess up the HW
441 * (interleaving)
442 */
312 y &= ~1; 443 y &= ~1;
313 444
445 if(y<0 || y>LCD_NATIVE_HEIGHT || x<0 || x>LCD_NATIVE_WIDTH
446 || height<0 || width <0)
447 {
448 return;
449 }
450
451 if(y+height>LCD_NATIVE_WIDTH)
452 {
453 height=LCD_NATIVE_WIDTH-y;
454 }
455 if(x+width>LCD_NATIVE_HEIGHT)
456 {
457 width=LCD_NATIVE_HEIGHT-x;
458 }
459
314 /* Sorry, but width and height must be >= 2 or else */ 460 /* Sorry, but width and height must be >= 2 or else */
315 width &= ~1; 461 width &= ~1;
316 height>>=1; 462 height>>=1;
317 463
318 fb_data *dst = (fb_data*)FRAME + LCD_WIDTH*LCD_HEIGHT - x * LCD_WIDTH + y; 464 fb_data * dst = FRAME + ((LCD_NATIVE_WIDTH+LCD_FUDGE)*(LCD_NATIVE_HEIGHT-1))
465 - (LCD_NATIVE_WIDTH+LCD_FUDGE)*x + y ;
319 466
320 z = stride*src_y; 467 z = stride*src_y;
321 yuv_src[0] = src[0] + z + src_x; 468 yuv_src[0] = src[0] + z + src_x;
@@ -337,11 +484,11 @@ void lcd_blit_yuv(unsigned char * const src[3],
337 /* This needs to be done in a block of 4 pixels */ 484 /* This needs to be done in a block of 4 pixels */
338 *c_dst=*c_yuv_src[0]<<8 | *c_yuv_src[1]; 485 *c_dst=*c_yuv_src[0]<<8 | *c_yuv_src[1];
339 *(c_dst+1)=*(c_yuv_src[0]+stride)<<8 | *c_yuv_src[2]; 486 *(c_dst+1)=*(c_yuv_src[0]+stride)<<8 | *c_yuv_src[2];
340 c_dst-=LCD_WIDTH; 487 c_dst-=(LCD_NATIVE_WIDTH+LCD_FUDGE);
341 c_yuv_src[0]++; 488 c_yuv_src[0]++;
342 *c_dst=*c_yuv_src[0]<<8 | *c_yuv_src[1]; 489 *c_dst=*c_yuv_src[0]<<8 | *c_yuv_src[1];
343 *(c_dst+1)=*(c_yuv_src[0]+stride)<<8 | *c_yuv_src[2]; 490 *(c_dst+1)=*(c_yuv_src[0]+stride)<<8 | *c_yuv_src[2];
344 c_dst-=LCD_WIDTH; 491 c_dst-=(LCD_NATIVE_WIDTH+LCD_FUDGE);
345 c_yuv_src[0]++; 492 c_yuv_src[0]++;
346 493
347 c_yuv_src[1]++; 494 c_yuv_src[1]++;