summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2008-03-23 00:28:16 +0000
committerJens Arnold <amiconn@rockbox.org>2008-03-23 00:28:16 +0000
commite03ef1ec23eb783b5675ad4dd66d58f0a38688c3 (patch)
treeeadf369b14560b77ffaf581fa1213cadbc8db796
parentad6cbbdd3cd5361febf22b502806507fd3f3a5a9 (diff)
downloadrockbox-e03ef1ec23eb783b5675ad4dd66d58f0a38688c3.tar.gz
rockbox-e03ef1ec23eb783b5675ad4dd66d58f0a38688c3.zip
LCd extension lib: Implement proper scrolling for 2 bit vertical interleaved LCD. Stops oscilloscope from crashing on M3. * A few small simplifications.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16754 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/lib/xlcd_scroll.c117
1 files changed, 86 insertions, 31 deletions
diff --git a/apps/plugins/lib/xlcd_scroll.c b/apps/plugins/lib/xlcd_scroll.c
index 1e6ad071fc..076c0547e9 100644
--- a/apps/plugins/lib/xlcd_scroll.c
+++ b/apps/plugins/lib/xlcd_scroll.c
@@ -25,6 +25,10 @@
25#ifdef HAVE_LCD_BITMAP 25#ifdef HAVE_LCD_BITMAP
26#include "xlcd.h" 26#include "xlcd.h"
27 27
28#if (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
29static const unsigned short patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000};
30#endif
31
28#if (LCD_PIXELFORMAT == HORIZONTAL_PACKING) && (LCD_DEPTH < 8) 32#if (LCD_PIXELFORMAT == HORIZONTAL_PACKING) && (LCD_DEPTH < 8)
29 33
30/* Scroll left */ 34/* Scroll left */
@@ -149,11 +153,7 @@ void xlcd_scroll_left(int count)
149 return; 153 return;
150 154
151 data = _xlcd_rb->lcd_framebuffer; 155 data = _xlcd_rb->lcd_framebuffer;
152#if LCD_DEPTH >= 8 156 data_end = data + LCD_WIDTH*LCD_FBHEIGHT;
153 data_end = data + LCD_WIDTH*LCD_HEIGHT;
154#else
155 data_end = data + LCD_WIDTH*((LCD_HEIGHT*LCD_DEPTH+7)/8);
156#endif
157 length = LCD_WIDTH - count; 157 length = LCD_WIDTH - count;
158 158
159 do 159 do
@@ -179,11 +179,7 @@ void xlcd_scroll_right(int count)
179 return; 179 return;
180 180
181 data = _xlcd_rb->lcd_framebuffer; 181 data = _xlcd_rb->lcd_framebuffer;
182#if LCD_DEPTH >= 8 182 data_end = data + LCD_WIDTH*LCD_FBHEIGHT;
183 data_end = data + LCD_WIDTH*LCD_HEIGHT;
184#else
185 data_end = data + LCD_WIDTH*((LCD_HEIGHT*LCD_DEPTH+7)/8);
186#endif
187 length = LCD_WIDTH - count; 183 length = LCD_WIDTH - count;
188 184
189 do 185 do
@@ -243,7 +239,8 @@ void xlcd_scroll_down(int count)
243 _xlcd_rb->lcd_set_drawmode(oldmode); 239 _xlcd_rb->lcd_set_drawmode(oldmode);
244} 240}
245 241
246#else /* LCD_PIXELFORMAT vertical packed */ 242#else /* LCD_PIXELFORMAT == VERTICAL_PACKING,
243 LCD_PIXELFORMAT == VERTICAL_INTERLEAVED */
247 244
248/* Scroll up */ 245/* Scroll up */
249void xlcd_scroll_up(int count) 246void xlcd_scroll_up(int count)
@@ -254,24 +251,26 @@ void xlcd_scroll_up(int count)
254 if ((unsigned) count >= LCD_HEIGHT) 251 if ((unsigned) count >= LCD_HEIGHT)
255 return; 252 return;
256 253
257#if LCD_DEPTH == 1 254#if (LCD_DEPTH == 1) \
255 || (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
258 blockcount = count >> 3; 256 blockcount = count >> 3;
259 blocklen = ((LCD_HEIGHT+7)/8) - blockcount;
260 bitcount = count & 7; 257 bitcount = count & 7;
261#elif LCD_DEPTH == 2 258#elif (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_PACKING)
262 blockcount = count >> 2; 259 blockcount = count >> 2;
263 blocklen = ((LCD_HEIGHT+3)/4) - blockcount;
264 bitcount = 2 * (count & 3); 260 bitcount = 2 * (count & 3);
265#endif 261#endif
262 blocklen = LCD_FBHEIGHT - blockcount;
266 263
267 if (blockcount) 264 if (blockcount)
268 { 265 {
269 _xlcd_rb->memmove(_xlcd_rb->lcd_framebuffer, 266 _xlcd_rb->memmove(_xlcd_rb->lcd_framebuffer,
270 _xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH, 267 _xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH,
271 blocklen * LCD_FBWIDTH); 268 blocklen * LCD_FBWIDTH * sizeof(fb_data));
272 } 269 }
273 if (bitcount) 270 if (bitcount)
274 { 271 {
272#if LCD_PIXELFORMAT == VERTICAL_PACKING
273
275#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) 274#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
276 asm ( 275 asm (
277 "mov #0,r4 \n" /* x = 0 */ 276 "mov #0,r4 \n" /* x = 0 */
@@ -384,17 +383,15 @@ void xlcd_scroll_up(int count)
384 unsigned char *addr = _xlcd_rb->lcd_framebuffer + blocklen * LCD_FBWIDTH; 383 unsigned char *addr = _xlcd_rb->lcd_framebuffer + blocklen * LCD_FBWIDTH;
385#if LCD_DEPTH == 2 384#if LCD_DEPTH == 2
386 unsigned fill = 0x55 * (~_xlcd_rb->lcd_get_background() & 3); 385 unsigned fill = 0x55 * (~_xlcd_rb->lcd_get_background() & 3);
386#else
387 const unsigned fill = 0;
387#endif 388#endif
388 389
389 for (x = 0; x < LCD_WIDTH; x++) 390 for (x = 0; x < LCD_WIDTH; x++)
390 { 391 {
391 unsigned char *col_addr = addr++; 392 unsigned char *col_addr = addr++;
392#if LCD_DEPTH == 1
393 unsigned data = 0;
394#else
395 unsigned data = fill; 393 unsigned data = fill;
396#endif 394
397
398 for (by = 0; by < blocklen; by++) 395 for (by = 0; by < blocklen; by++)
399 { 396 {
400 col_addr -= LCD_FBWIDTH; 397 col_addr -= LCD_FBWIDTH;
@@ -403,6 +400,35 @@ void xlcd_scroll_up(int count)
403 } 400 }
404 } 401 }
405#endif /* CPU, LCD_DEPTH */ 402#endif /* CPU, LCD_DEPTH */
403
404#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
405
406#if LCD_DEPTH == 2
407 int x, by;
408 fb_data *addr = _xlcd_rb->lcd_framebuffer + blocklen * LCD_FBWIDTH;
409 unsigned fill, mask;
410
411 fill = patterns[_xlcd_rb->lcd_get_background() & 3] << 8;
412 mask = (0xFFu >> bitcount) << bitcount;
413 mask |= mask << 8;
414
415 for (x = 0; x < LCD_WIDTH; x++)
416 {
417 fb_data *col_addr = addr++;
418 unsigned olddata = fill;
419 unsigned data;
420
421 for (by = 0; by < blocklen; by++)
422 {
423 col_addr -= LCD_FBWIDTH;
424 data = *col_addr;
425 *col_addr = (olddata ^ ((data ^ olddata) & mask)) >> bitcount;
426 olddata = data << 8;
427 }
428 }
429#endif /* LCD_DEPTH == 2 */
430
431#endif /* LCD_PIXELFORMAT */
406 } 432 }
407 oldmode = _xlcd_rb->lcd_get_drawmode(); 433 oldmode = _xlcd_rb->lcd_get_drawmode();
408 _xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 434 _xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
@@ -419,24 +445,26 @@ void xlcd_scroll_down(int count)
419 if ((unsigned) count >= LCD_HEIGHT) 445 if ((unsigned) count >= LCD_HEIGHT)
420 return; 446 return;
421 447
422#if LCD_DEPTH == 1 448#if (LCD_DEPTH == 1) \
449 || (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
423 blockcount = count >> 3; 450 blockcount = count >> 3;
424 blocklen = ((LCD_HEIGHT+7)/8) - blockcount;
425 bitcount = count & 7; 451 bitcount = count & 7;
426#elif LCD_DEPTH == 2 452#elif (LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_PACKING)
427 blockcount = count >> 2; 453 blockcount = count >> 2;
428 blocklen = ((LCD_HEIGHT+3)/4) - blockcount;
429 bitcount = 2 * (count & 3); 454 bitcount = 2 * (count & 3);
430#endif 455#endif
456 blocklen = LCD_FBHEIGHT - blockcount;
431 457
432 if (blockcount) 458 if (blockcount)
433 { 459 {
434 _xlcd_rb->memmove(_xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH, 460 _xlcd_rb->memmove(_xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH,
435 _xlcd_rb->lcd_framebuffer, 461 _xlcd_rb->lcd_framebuffer,
436 blocklen * LCD_FBWIDTH); 462 blocklen * LCD_FBWIDTH * sizeof(fb_data));
437 } 463 }
438 if (bitcount) 464 if (bitcount)
439 { 465 {
466#if LCD_PIXELFORMAT == VERTICAL_PACKING
467
440#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) 468#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
441 asm ( 469 asm (
442 "mov #0,r4 \n" /* x = 0 */ 470 "mov #0,r4 \n" /* x = 0 */
@@ -545,17 +573,15 @@ void xlcd_scroll_down(int count)
545 unsigned char *addr = _xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH; 573 unsigned char *addr = _xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH;
546#if LCD_DEPTH == 2 574#if LCD_DEPTH == 2
547 unsigned fill = (0x55 * (~_xlcd_rb->lcd_get_background() & 3)) << bitcount; 575 unsigned fill = (0x55 * (~_xlcd_rb->lcd_get_background() & 3)) << bitcount;
576#else
577 const unsigned fill = 0;
548#endif 578#endif
549 579
550 for (x = 0; x < LCD_WIDTH; x++) 580 for (x = 0; x < LCD_WIDTH; x++)
551 { 581 {
552 unsigned char *col_addr = addr++; 582 unsigned char *col_addr = addr++;
553#if LCD_DEPTH == 1
554 unsigned data = 0;
555#else
556 unsigned data = fill; 583 unsigned data = fill;
557#endif 584
558
559 for (by = 0; by < blocklen; by++) 585 for (by = 0; by < blocklen; by++)
560 { 586 {
561 data = (data >> 8) | (*col_addr << bitcount); 587 data = (data >> 8) | (*col_addr << bitcount);
@@ -564,6 +590,35 @@ void xlcd_scroll_down(int count)
564 } 590 }
565 } 591 }
566#endif /* CPU, LCD_DEPTH */ 592#endif /* CPU, LCD_DEPTH */
593
594#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
595
596#if LCD_DEPTH == 2
597 int x, by;
598 fb_data *addr = _xlcd_rb->lcd_framebuffer + blockcount * LCD_FBWIDTH;
599 unsigned fill, mask;
600
601 fill = patterns[_xlcd_rb->lcd_get_background() & 3] >> (8 - bitcount);
602 mask = (0xFFu >> bitcount) << bitcount;
603 mask |= mask << 8;
604
605 for (x = 0; x < LCD_WIDTH; x++)
606 {
607 fb_data *col_addr = addr++;
608 unsigned olddata = fill;
609 unsigned data;
610
611 for (by = 0; by < blocklen; by++)
612 {
613 data = *col_addr << bitcount;
614 *col_addr = olddata ^ ((data ^ olddata) & mask);
615 olddata = data >> 8;
616 col_addr += LCD_FBWIDTH;
617 }
618 }
619#endif /* LCD_DEPTH == 2 */
620
621#endif /* LCD_PIXELFORMAT */
567 } 622 }
568 oldmode = _xlcd_rb->lcd_get_drawmode(); 623 oldmode = _xlcd_rb->lcd_get_drawmode();
569 _xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 624 _xlcd_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);