diff options
author | Jens Arnold <amiconn@rockbox.org> | 2008-03-23 00:28:16 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2008-03-23 00:28:16 +0000 |
commit | e03ef1ec23eb783b5675ad4dd66d58f0a38688c3 (patch) | |
tree | eadf369b14560b77ffaf581fa1213cadbc8db796 | |
parent | ad6cbbdd3cd5361febf22b502806507fd3f3a5a9 (diff) | |
download | rockbox-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.c | 117 |
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) | ||
29 | static 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 */ |
249 | void xlcd_scroll_up(int count) | 246 | void 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); |