diff options
Diffstat (limited to 'firmware/target/arm/tms320dm320')
-rw-r--r-- | firmware/target/arm/tms320dm320/app.lds | 57 | ||||
-rw-r--r-- | firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c | 241 |
2 files changed, 225 insertions, 73 deletions
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) | |||
6 | OUTPUT_ARCH(arm) | 6 | OUTPUT_ARCH(arm) |
7 | STARTUP(target/arm/tms320dm320/crt0.o) | 7 | STARTUP(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 | ||
39 | MEMORY | 34 | MEMORY |
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) | ||
357 | void 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 | |||
396 | void 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]++; |