summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-09-30 20:10:27 +0000
committerJens Arnold <amiconn@rockbox.org>2005-09-30 20:10:27 +0000
commit1a40e109333b8206140594fce746f7972a4d0d86 (patch)
treea4f0589682ae4f8c894222b7691efebd989d763f /apps/plugins
parent8b9c64f19db3abf8872b8dd85ea8ee1343f322e3 (diff)
downloadrockbox-1a40e109333b8206140594fce746f7972a4d0d86.tar.gz
rockbox-1a40e109333b8206140594fce746f7972a4d0d86.zip
H1x0: Changed lcd_blit() and the grayscale library to use the same internal format as on archos (1bpp). While the slowdown of the ISR is minimal (the intermediate buffers are in IRAM), the planar grayscale buffer takes only half the space for a given depth, and gray_update[_rect]() and unbuffered drawing/scrolling are faster because less data needs to be moved. It should also make porting of video.rock somewhat easier. * Archos recorders, Ondios: Some slight optimisations of the grayscale library.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7571 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/grayscale.c6
-rw-r--r--apps/plugins/jpeg.c4
-rw-r--r--apps/plugins/lib/gray.h4
-rw-r--r--apps/plugins/lib/gray_core.c132
-rw-r--r--apps/plugins/lib/gray_draw.c58
-rw-r--r--apps/plugins/lib/gray_scroll.c12
-rw-r--r--apps/plugins/mandelbrot.c4
7 files changed, 127 insertions, 93 deletions
diff --git a/apps/plugins/grayscale.c b/apps/plugins/grayscale.c
index 3b86304123..cdb3f880e5 100644
--- a/apps/plugins/grayscale.c
+++ b/apps/plugins/grayscale.c
@@ -154,11 +154,11 @@ int main(void)
154 32 bitplanes for 33 shades of grey. 154 32 bitplanes for 33 shades of grey.
155 H1x0: 160 pixels wide, 30 rows (120 pixels) high, (try to) reserve 155 H1x0: 160 pixels wide, 30 rows (120 pixels) high, (try to) reserve
156 32 bitplanes for 33 shades of grey. */ 156 32 bitplanes for 33 shades of grey. */
157 shades = gray_init(rb, gbuf, gbuf_size, true, LCD_WIDTH, 157 shades = gray_init(rb, gbuf, gbuf_size, true, LCD_WIDTH, GFX_HEIGHT/8,
158 (GFX_HEIGHT*LCD_DEPTH/8), 32, NULL) + 1; 158 32, NULL) + 1;
159 159
160 /* place greyscale overlay 1 row down */ 160 /* place greyscale overlay 1 row down */
161 gray_set_position(0, LCD_DEPTH); 161 gray_set_position(0, 1);
162 162
163 rb->snprintf(pbuf, sizeof(pbuf), "Shades: %d", shades); 163 rb->snprintf(pbuf, sizeof(pbuf), "Shades: %d", shades);
164 rb->lcd_puts(0, 0, pbuf); 164 rb->lcd_puts(0, 0, pbuf);
diff --git a/apps/plugins/jpeg.c b/apps/plugins/jpeg.c
index 1aac438e51..f9dcf2a63d 100644
--- a/apps/plugins/jpeg.c
+++ b/apps/plugins/jpeg.c
@@ -1822,8 +1822,8 @@ int main(char* filename)
1822 1822
1823 1823
1824 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */ 1824 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */
1825 grayscales = gray_init(rb, buf, buf_size, false, LCD_WIDTH, 1825 grayscales = gray_init(rb, buf, buf_size, false, LCD_WIDTH, LCD_HEIGHT/8,
1826 (LCD_HEIGHT*LCD_DEPTH/8), 32, &graysize) + 1; 1826 32, &graysize) + 1;
1827 buf += graysize; 1827 buf += graysize;
1828 buf_size -= graysize; 1828 buf_size -= graysize;
1829 if (grayscales < 33 || buf_size <= 0) 1829 if (grayscales < 33 || buf_size <= 0)
diff --git a/apps/plugins/lib/gray.h b/apps/plugins/lib/gray.h
index 09ae73b8a6..f1007984b5 100644
--- a/apps/plugins/lib/gray.h
+++ b/apps/plugins/lib/gray.h
@@ -107,11 +107,7 @@ void gray_ub_scroll_down(int count);
107 107
108/*** Internal stuff ***/ 108/*** Internal stuff ***/
109 109
110#if LCD_DEPTH == 1
111#define _PBLOCK_EXP 3 110#define _PBLOCK_EXP 3
112#elif LCD_DEPTH == 2
113#define _PBLOCK_EXP 2
114#endif
115#define _PBLOCK (1 << _PBLOCK_EXP) 111#define _PBLOCK (1 << _PBLOCK_EXP)
116 112
117/* flag definitions */ 113/* flag definitions */
diff --git a/apps/plugins/lib/gray_core.c b/apps/plugins/lib/gray_core.c
index a4ef45d8c1..ecff53f1c5 100644
--- a/apps/plugins/lib/gray_core.c
+++ b/apps/plugins/lib/gray_core.c
@@ -81,10 +81,8 @@ static void _timer_isr(void)
81 memory. Unbuffered operation provides only a subset of 81 memory. Unbuffered operation provides only a subset of
82 drawing functions. (only gray_bitmap drawing and scrolling) 82 drawing functions. (only gray_bitmap drawing and scrolling)
83 width = width in pixels (1..LCD_WIDTH) 83 width = width in pixels (1..LCD_WIDTH)
84 bheight = height in LCD pixel-block units (8 pixels for b&w LCD, 84 bheight = height in LCD pixel-block units (8 pixels) (1..LCD_HEIGHT/8)
85 4 pixels for 4-grey LCD) (1..LCD_HEIGHT/block_size) 85 depth = number of bitplanes to use (1..32).
86 depth = number of bitplanes to use (1..32 for b&w LCD, 1..16 for
87 4-grey LCD).
88 86
89 result: 87 result:
90 = depth if there was enough memory 88 = depth if there was enough memory
@@ -99,8 +97,7 @@ static void _timer_isr(void)
99 deliver an enhancement over the native display. 97 deliver an enhancement over the native display.
100 98
101 The number of displayable shades is calculated as follows: 99 The number of displayable shades is calculated as follows:
102 b&w LCD: shades = depth + 1 100 shades = depth + 1
103 4-grey LCD: shades = 3 * depth + 1
104 101
105 If you need info about the memory taken by the greyscale buffer, supply a 102 If you need info about the memory taken by the greyscale buffer, supply a
106 long* as the last parameter. This long will then contain the number of bytes 103 long* as the last parameter. This long will then contain the number of bytes
@@ -109,7 +106,7 @@ static void _timer_isr(void)
109 shades * sizeof(long) (bitpatterns) 106 shades * sizeof(long) (bitpatterns)
110 + (width * bheight) * depth (bitplane data) 107 + (width * bheight) * depth (bitplane data)
111 + buffered ? (chunky front- & backbuffer) 108 + buffered ? (chunky front- & backbuffer)
112 (width * bheight * 8(4) * 2) : 0 109 (width * bheight * 8 * 2) : 0
113 + 0..3 (longword alignment) */ 110 + 0..3 (longword alignment) */
114int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, 111int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
115 bool buffered, int width, int bheight, int depth, long *buf_taken) 112 bool buffered, int width, int bheight, int depth, long *buf_taken)
@@ -292,42 +289,41 @@ void gray_update_rect(int x, int y, int width, int height)
292#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) 289#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
293 unsigned long pat_stack[8]; 290 unsigned long pat_stack[8];
294 unsigned long *pat_ptr; 291 unsigned long *pat_ptr;
295 unsigned change, ofs; 292 unsigned char *cbuf, *bbuf;
293 unsigned change;
294
295 cbuf = _gray_info.cur_buffer + srcofs_row;
296 bbuf = _gray_info.back_buffer + srcofs_row;
296 297
297 ofs = srcofs_row;
298 asm volatile ( 298 asm volatile (
299 "mov.l @(%[ofs],%[cbuf]),r1\n" 299 "mov.l @%[cbuf]+,r1 \n"
300 "mov.l @(%[ofs],%[bbuf]),r2\n" 300 "mov.l @%[bbuf]+,r2 \n"
301 "xor r1,r2 \n" 301 "xor r1,r2 \n"
302 "add #4,%[ofs] \n" 302 "mov.l @%[cbuf],r1 \n"
303 "mov.l @(%[ofs],%[cbuf]),r1\n" 303 "mov.l @%[bbuf],%[chg] \n"
304 "mov.l @(%[ofs],%[bbuf]),%[chg]\n"
305 "xor r1,%[chg] \n" 304 "xor r1,%[chg] \n"
306 "or r2,%[chg] \n" 305 "or r2,%[chg] \n"
307 : /* outputs */ 306 : /* outputs */
308 [ofs] "+z"(ofs), 307 [cbuf]"+r"(cbuf),
308 [bbuf]"+r"(bbuf),
309 [chg] "=r"(change) 309 [chg] "=r"(change)
310 : /* inputs */ 310 : /* inputs */
311 [cbuf]"r"(_gray_info.cur_buffer),
312 [bbuf]"r"(_gray_info.back_buffer)
313 : /* clobbers */ 311 : /* clobbers */
314 "r1", "r2" 312 "r1", "r2"
315 ); 313 );
316 314
317 if (change != 0) 315 if (change != 0)
318 { 316 {
319 unsigned char *cbuf, *bbuf, *addr, *end; 317 unsigned char *addr, *end;
320 unsigned mask; 318 unsigned mask;
321 319
322 pat_ptr = &pat_stack[8]; 320 pat_ptr = &pat_stack[8];
323 cbuf = _gray_info.cur_buffer; 321 cbuf = _gray_info.cur_buffer + srcofs_row;
324 bbuf = _gray_info.back_buffer; 322 bbuf = _gray_info.back_buffer + srcofs_row;
325 323
326 /* precalculate the bit patterns with random shifts 324 /* precalculate the bit patterns with random shifts
327 * for all 8 pixels and put them on an extra "stack" */ 325 * for all 8 pixels and put them on an extra "stack" */
328 asm volatile ( 326 asm volatile (
329 "add %[ofs],%[cbuf] \n"
330 "add %[ofs],%[bbuf] \n"
331 "mov #8,r3 \n" /* loop count in r3: 8 pixels */ 327 "mov #8,r3 \n" /* loop count in r3: 8 pixels */
332 328
333 ".ur_pre_loop: \n" 329 ".ur_pre_loop: \n"
@@ -384,7 +380,6 @@ void gray_update_rect(int x, int y, int width, int height)
384 [patp]"+r"(pat_ptr), 380 [patp]"+r"(pat_ptr),
385 [mask]"=&r"(mask) 381 [mask]"=&r"(mask)
386 : /* inputs */ 382 : /* inputs */
387 [ofs] "[mask]"(srcofs_row),
388 [dpth]"r"(_gray_info.depth), 383 [dpth]"r"(_gray_info.depth),
389 [bpat]"r"(_gray_info.bitpattern), 384 [bpat]"r"(_gray_info.bitpattern),
390 [rmsk]"r"(_gray_info.randmask) 385 [rmsk]"r"(_gray_info.randmask)
@@ -473,36 +468,44 @@ void gray_update_rect(int x, int y, int width, int height)
473 ); 468 );
474 } 469 }
475#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) 470#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2)
476 unsigned long pat_stack[4]; 471 unsigned long pat_stack[8];
477 unsigned long *pat_ptr; 472 unsigned long *pat_ptr;
473 unsigned char *cbuf, *bbuf;
478 unsigned change; 474 unsigned change;
479 475
476 cbuf = _gray_info.cur_buffer + srcofs_row;
477 bbuf = _gray_info.back_buffer + srcofs_row;
478
480 asm volatile ( 479 asm volatile (
481 "move.l (%[ofs]:l:1,%[cbuf]),%[chg] \n" 480 "move.l (%[cbuf])+,%%d0 \n"
482 "sub.l (%[ofs]:l:1,%[bbuf]),%[chg] \n" 481 "move.l (%[bbuf])+,%%d1 \n"
482 "eor.l %%d0,%%d1 \n"
483 "move.l (%[cbuf]),%%d0 \n"
484 "move.l (%[bbuf]),%[chg]\n"
485 "eor.l %%d0,%[chg] \n"
486 "or.l %%d1,%[chg] \n"
483 : /* outputs */ 487 : /* outputs */
488 [cbuf]"+a"(cbuf),
489 [bbuf]"+a"(bbuf),
484 [chg] "=&d"(change) 490 [chg] "=&d"(change)
485 : /* inputs */ 491 : /* inputs */
486 [cbuf]"a"(_gray_info.cur_buffer), 492 : /* clobbers */
487 [bbuf]"a"(_gray_info.back_buffer), 493 "d0", "d1"
488 [ofs] "d"(srcofs_row)
489 ); 494 );
490 495
491 if (change != 0) 496 if (change != 0)
492 { 497 {
493 unsigned char *cbuf, *bbuf, *addr, *end; 498 unsigned char *addr, *end;
494 unsigned mask; 499 unsigned mask;
495 500
496 pat_ptr = &pat_stack[4]; 501 pat_ptr = &pat_stack[8];
497 cbuf = _gray_info.cur_buffer; 502 cbuf = _gray_info.cur_buffer + srcofs_row;
498 bbuf = _gray_info.back_buffer; 503 bbuf = _gray_info.back_buffer + srcofs_row;
499 504
500 /* precalculate the bit patterns with random shifts 505 /* precalculate the bit patterns with random shifts
501 * for all 4 pixels and put them on an extra "stack" */ 506 * for all 8 pixels and put them on an extra "stack" */
502 asm volatile ( 507 asm volatile (
503 "add.l %[ofs],%[cbuf] \n" 508 "moveq.l #8,%%d3 \n" /* loop count in d3: 8 pixels */
504 "add.l %[ofs],%[bbuf] \n"
505 "moveq.l #4,%%d3 \n" /* loop count in d3: 4 pixels */
506 "clr.l %[mask] \n" 509 "clr.l %[mask] \n"
507 510
508 ".ur_pre_loop: \n" 511 ".ur_pre_loop: \n"
@@ -536,10 +539,10 @@ void gray_update_rect(int x, int y, int width, int height)
536 "lsr.l %%d1,%%d2 \n" 539 "lsr.l %%d1,%%d2 \n"
537 "or.l %%d0,%%d2 \n" /* rotated_pattern = d2 | d0 */ 540 "or.l %%d0,%%d2 \n" /* rotated_pattern = d2 | d0 */
538 541
539 "or.l #0x0300,%[mask] \n" /* set mask bit */ 542 "or.l #0x0100,%[mask] \n" /* set mask bit */
540 543
541 ".ur_skip: \n" 544 ".ur_skip: \n"
542 "lsr.l #2,%[mask] \n" /* shift mask */ 545 "lsr.l #1,%[mask] \n" /* shift mask */
543 "move.l %%d2,-(%[patp]) \n" /* push on pattern stack */ 546 "move.l %%d2,-(%[patp]) \n" /* push on pattern stack */
544 547
545 "subq.l #1,%%d3 \n" /* decrease loop count */ 548 "subq.l #1,%%d3 \n" /* decrease loop count */
@@ -551,7 +554,6 @@ void gray_update_rect(int x, int y, int width, int height)
551 [rnd] "+d"(_gray_random_buffer), 554 [rnd] "+d"(_gray_random_buffer),
552 [mask]"=&d"(mask) 555 [mask]"=&d"(mask)
553 : /* inputs */ 556 : /* inputs */
554 [ofs] "[mask]"(srcofs_row),
555 [bpat]"a"(_gray_info.bitpattern), 557 [bpat]"a"(_gray_info.bitpattern),
556 [dpth]"d"(_gray_info.depth), 558 [dpth]"d"(_gray_info.depth),
557 [rmsk]"d"(_gray_info.randmask) 559 [rmsk]"d"(_gray_info.randmask)
@@ -562,11 +564,11 @@ void gray_update_rect(int x, int y, int width, int height)
562 addr = dst_row; 564 addr = dst_row;
563 end = addr + MULU16(_gray_info.depth, _gray_info.plane_size); 565 end = addr + MULU16(_gray_info.depth, _gray_info.plane_size);
564 566
565 /* set the bits for all 4 pixels in all bytes according to the 567 /* set the bits for all 8 pixels in all bytes according to the
566 * precalculated patterns on the pattern stack */ 568 * precalculated patterns on the pattern stack */
567 asm volatile ( 569 asm volatile (
568 "movem.l (%[patp]),%%d2-%%d5 \n" /* pop all 4 patterns */ 570 "movem.l (%[patp]),%%d2-%%d6/%%a0-%%a2 \n"
569 571 /* pop all 8 patterns */
570 "not.l %[mask] \n" /* set mask -> keep mask */ 572 "not.l %[mask] \n" /* set mask -> keep mask */
571 "and.l #0xFF,%[mask] \n" 573 "and.l #0xFF,%[mask] \n"
572 "beq.b .ur_sloop \n" /* yes: jump to short loop */ 574 "beq.b .ur_sloop \n" /* yes: jump to short loop */
@@ -575,18 +577,26 @@ void gray_update_rect(int x, int y, int width, int height)
575 "clr.l %%d0 \n" 577 "clr.l %%d0 \n"
576 "lsr.l #1,%%d2 \n" /* shift out mask bit */ 578 "lsr.l #1,%%d2 \n" /* shift out mask bit */
577 "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */ 579 "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */
578 "lsl.l #1,%%d0 \n" /* shift by another 1 for a total of 2 */
579 "lsr.l #1,%%d3 \n" 580 "lsr.l #1,%%d3 \n"
580 "addx.l %%d0,%%d0 \n" 581 "addx.l %%d0,%%d0 \n"
581 "lsl.l #1,%%d0 \n"
582 "lsr.l #1,%%d4 \n" 582 "lsr.l #1,%%d4 \n"
583 "addx.l %%d0,%%d0 \n" 583 "addx.l %%d0,%%d0 \n"
584 "lsl.l #1,%%d0 \n"
585 "lsr.l #1,%%d5 \n" 584 "lsr.l #1,%%d5 \n"
586 "addx.l %%d0,%%d0 \n" 585 "addx.l %%d0,%%d0 \n"
587 "move.l %%d0,%%d1 \n" /* duplicate bits 0, 2, 4, 6, ... */ 586 "lsr.l #1,%%d6 \n"
588 "lsl.l #1,%%d1 \n" /* to 1, 3, 5, 7, ... */ 587 "addx.l %%d0,%%d0 \n"
589 "or.l %%d1,%%d0 \n" 588 "move.l %%a0,%%d1 \n"
589 "lsr.l #1,%%d1 \n"
590 "addx.l %%d0,%%d0 \n"
591 "move.l %%d1,%%a0 \n"
592 "move.l %%a1,%%d1 \n"
593 "lsr.l #1,%%d1 \n"
594 "addx.l %%d0,%%d0 \n"
595 "move.l %%d1,%%a1 \n"
596 "move.l %%a2,%%d1 \n"
597 "lsr.l #1,%%d1 \n"
598 "addx.l %%d0,%%d0 \n"
599 "move.l %%d1,%%a2 \n"
590 600
591 "move.b (%[addr]),%%d1 \n" /* read old value */ 601 "move.b (%[addr]),%%d1 \n" /* read old value */
592 "and.l %[mask],%%d1 \n" /* mask out unneeded bits */ 602 "and.l %[mask],%%d1 \n" /* mask out unneeded bits */
@@ -603,18 +613,26 @@ void gray_update_rect(int x, int y, int width, int height)
603 "clr.l %%d0 \n" 613 "clr.l %%d0 \n"
604 "lsr.l #1,%%d2 \n" /* shift out mask bit */ 614 "lsr.l #1,%%d2 \n" /* shift out mask bit */
605 "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */ 615 "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */
606 "lsl.l #1,%%d0 \n" /* shift by another 1 for a total of 2 */
607 "lsr.l #1,%%d3 \n" 616 "lsr.l #1,%%d3 \n"
608 "addx.l %%d0,%%d0 \n" 617 "addx.l %%d0,%%d0 \n"
609 "lsl.l #1,%%d0 \n"
610 "lsr.l #1,%%d4 \n" 618 "lsr.l #1,%%d4 \n"
611 "addx.l %%d0,%%d0 \n" 619 "addx.l %%d0,%%d0 \n"
612 "lsl.l #1,%%d0 \n"
613 "lsr.l #1,%%d5 \n" 620 "lsr.l #1,%%d5 \n"
614 "addx.l %%d0,%%d0 \n" 621 "addx.l %%d0,%%d0 \n"
615 "move.l %%d0,%%d1 \n" /* duplicate bits 0, 2, 4, 6, ... */ 622 "lsr.l #1,%%d6 \n"
616 "lsl.l #1,%%d1 \n" /* to 1, 3, 5, 7, ... */ 623 "addx.l %%d0,%%d0 \n"
617 "or.l %%d1,%%d0 \n" 624 "move.l %%a0,%%d1 \n"
625 "lsr.l #1,%%d1 \n"
626 "addx.l %%d0,%%d0 \n"
627 "move.l %%d1,%%a0 \n"
628 "move.l %%a1,%%d1 \n"
629 "lsr.l #1,%%d1 \n"
630 "addx.l %%d0,%%d0 \n"
631 "move.l %%d1,%%a1 \n"
632 "move.l %%a2,%%d1 \n"
633 "lsr.l #1,%%d1 \n"
634 "addx.l %%d0,%%d0 \n"
635 "move.l %%d1,%%a2 \n"
618 636
619 "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */ 637 "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */
620 "add.l %[psiz],%[addr] \n" /* advance to next bitplane */ 638 "add.l %[psiz],%[addr] \n" /* advance to next bitplane */
@@ -626,11 +644,11 @@ void gray_update_rect(int x, int y, int width, int height)
626 [addr]"+a"(addr), 644 [addr]"+a"(addr),
627 [mask]"+d"(mask) 645 [mask]"+d"(mask)
628 : /* inputs */ 646 : /* inputs */
629 [psiz]"r"(_gray_info.plane_size), 647 [psiz]"a"(_gray_info.plane_size),
630 [end] "a"(end), 648 [end] "a"(end),
631 [patp]"a"(pat_ptr) 649 [patp]"a"(pat_ptr)
632 : /* clobbers */ 650 : /* clobbers */
633 "d0", "d1", "d2", "d3", "d4", "d5" 651 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1", "a2"
634 ); 652 );
635 } 653 }
636#endif 654#endif
diff --git a/apps/plugins/lib/gray_draw.c b/apps/plugins/lib/gray_draw.c
index ab1b286137..4b2237197c 100644
--- a/apps/plugins/lib/gray_draw.c
+++ b/apps/plugins/lib/gray_draw.c
@@ -754,13 +754,13 @@ static void _writearray(unsigned char *address, const unsigned char *src,
754 _src = src; 754 _src = src;
755 755
756 /* precalculate the bit patterns with random shifts 756 /* precalculate the bit patterns with random shifts
757 for all 4 pixels and put them on an extra "stack" */ 757 for all 8 pixels and put them on an extra "stack" */
758 asm volatile ( 758 asm volatile (
759 "moveq.l #4,%%d3 \n" /* loop count in d3: 4 pixels */ 759 "moveq.l #8,%%d3 \n" /* loop count in d3: 4 pixels */
760 760
761 ".wa_loop: \n" /** load pattern for pixel **/ 761 ".wa_loop: \n" /** load pattern for pixel **/
762 "clr.l %%d2 \n" /* pattern for skipped pixel must be 0 */ 762 "clr.l %%d2 \n" /* pattern for skipped pixel must be 0 */
763 "lsr.l #2,%[mask] \n" /* shift out 2 lsbs of mask */ 763 "lsr.l #1,%[mask] \n" /* shift out 2 lsbs of mask */
764 "bcc.b .wa_skip \n" /* skip this pixel */ 764 "bcc.b .wa_skip \n" /* skip this pixel */
765 765
766 "clr.l %%d0 \n" 766 "clr.l %%d0 \n"
@@ -816,10 +816,10 @@ static void _writearray(unsigned char *address, const unsigned char *src,
816 end = addr + MULU16(_gray_info.depth, _gray_info.plane_size); 816 end = addr + MULU16(_gray_info.depth, _gray_info.plane_size);
817 _mask = mask; 817 _mask = mask;
818 818
819 /* set the bits for all 4 pixels in all bytes according to the 819 /* set the bits for all 8 pixels in all bytes according to the
820 * precalculated patterns on the pattern stack */ 820 * precalculated patterns on the pattern stack */
821 asm volatile ( 821 asm volatile (
822 "movem.l (%[patp]),%%d2-%%d5 \n" /* pop all 4 patterns */ 822 "movem.l (%[patp]),%%d2-%%d6/%%a0-%%a2 \n" /* pop all 8 patterns */
823 823
824 "not.l %[mask] \n" /* "set" mask -> "keep" mask */ 824 "not.l %[mask] \n" /* "set" mask -> "keep" mask */
825 "and.l #0xFF,%[mask] \n" 825 "and.l #0xFF,%[mask] \n"
@@ -829,18 +829,26 @@ static void _writearray(unsigned char *address, const unsigned char *src,
829 "clr.l %%d0 \n" 829 "clr.l %%d0 \n"
830 "lsr.l #1,%%d2 \n" /* shift out mask bit */ 830 "lsr.l #1,%%d2 \n" /* shift out mask bit */
831 "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */ 831 "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */
832 "lsl.l #1,%%d0 \n" /* shift by another 1 for a total of 2 */
833 "lsr.l #1,%%d3 \n" 832 "lsr.l #1,%%d3 \n"
834 "addx.l %%d0,%%d0 \n" 833 "addx.l %%d0,%%d0 \n"
835 "lsl.l #1,%%d0 \n"
836 "lsr.l #1,%%d4 \n" 834 "lsr.l #1,%%d4 \n"
837 "addx.l %%d0,%%d0 \n" 835 "addx.l %%d0,%%d0 \n"
838 "lsl.l #1,%%d0 \n"
839 "lsr.l #1,%%d5 \n" 836 "lsr.l #1,%%d5 \n"
840 "addx.l %%d0,%%d0 \n" 837 "addx.l %%d0,%%d0 \n"
841 "move.l %%d0,%%d1 \n" /* duplicate bits 0, 2, 4, 6, ... */ 838 "lsr.l #1,%%d6 \n"
842 "lsl.l #1,%%d1 \n" /* to 1, 3, 5, 7, ... */ 839 "addx.l %%d0,%%d0 \n"
843 "or.l %%d1,%%d0 \n" 840 "move.l %%a0,%%d1 \n"
841 "lsr.l #1,%%d1 \n"
842 "addx.l %%d0,%%d0 \n"
843 "move.l %%d1,%%a0 \n"
844 "move.l %%a1,%%d1 \n"
845 "lsr.l #1,%%d1 \n"
846 "addx.l %%d0,%%d0 \n"
847 "move.l %%d1,%%a1 \n"
848 "move.l %%a2,%%d1 \n"
849 "lsr.l #1,%%d1 \n"
850 "addx.l %%d0,%%d0 \n"
851 "move.l %%d1,%%a2 \n"
844 852
845 "move.b (%[addr]),%%d1 \n" /* read old value */ 853 "move.b (%[addr]),%%d1 \n" /* read old value */
846 "and.l %[mask],%%d1 \n" /* mask out unneeded bits */ 854 "and.l %[mask],%%d1 \n" /* mask out unneeded bits */
@@ -857,18 +865,26 @@ static void _writearray(unsigned char *address, const unsigned char *src,
857 "clr.l %%d0 \n" 865 "clr.l %%d0 \n"
858 "lsr.l #1,%%d2 \n" /* shift out mask bit */ 866 "lsr.l #1,%%d2 \n" /* shift out mask bit */
859 "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */ 867 "addx.l %%d0,%%d0 \n" /* puts bit into LSB, shifts left by 1 */
860 "lsl.l #1,%%d0 \n" /* shift by another 1 for a total of 2 */
861 "lsr.l #1,%%d3 \n" 868 "lsr.l #1,%%d3 \n"
862 "addx.l %%d0,%%d0 \n" 869 "addx.l %%d0,%%d0 \n"
863 "lsl.l #1,%%d0 \n"
864 "lsr.l #1,%%d4 \n" 870 "lsr.l #1,%%d4 \n"
865 "addx.l %%d0,%%d0 \n" 871 "addx.l %%d0,%%d0 \n"
866 "lsl.l #1,%%d0 \n"
867 "lsr.l #1,%%d5 \n" 872 "lsr.l #1,%%d5 \n"
868 "addx.l %%d0,%%d0 \n" 873 "addx.l %%d0,%%d0 \n"
869 "move.l %%d0,%%d1 \n" /* duplicate bits 0, 2, 4, 6, ... */ 874 "lsr.l #1,%%d6 \n"
870 "lsl.l #1,%%d1 \n" /* to 1, 3, 5, 7, ... */ 875 "addx.l %%d0,%%d0 \n"
871 "or.l %%d1,%%d0 \n" 876 "move.l %%a0,%%d1 \n"
877 "lsr.l #1,%%d1 \n"
878 "addx.l %%d0,%%d0 \n"
879 "move.l %%d1,%%a0 \n"
880 "move.l %%a1,%%d1 \n"
881 "lsr.l #1,%%d1 \n"
882 "addx.l %%d0,%%d0 \n"
883 "move.l %%d1,%%a1 \n"
884 "move.l %%a2,%%d1 \n"
885 "lsr.l #1,%%d1 \n"
886 "addx.l %%d0,%%d0 \n"
887 "move.l %%d1,%%a2 \n"
872 888
873 "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */ 889 "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */
874 "add.l %[psiz],%[addr] \n" /* advance to next bitplane */ 890 "add.l %[psiz],%[addr] \n" /* advance to next bitplane */
@@ -880,11 +896,11 @@ static void _writearray(unsigned char *address, const unsigned char *src,
880 [addr]"+a"(addr), 896 [addr]"+a"(addr),
881 [mask]"+d"(_mask) 897 [mask]"+d"(_mask)
882 : /* inputs */ 898 : /* inputs */
883 [psiz]"r"(_gray_info.plane_size), 899 [psiz]"a"(_gray_info.plane_size),
884 [end] "a"(end), 900 [end] "a"(end),
885 [patp]"a"(pat_ptr) 901 [patp]"a"(pat_ptr)
886 : /* clobbers */ 902 : /* clobbers */
887 "d0", "d1", "d2", "d3", "d4", "d5" 903 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1", "a2"
888 ); 904 );
889#endif 905#endif
890} 906}
@@ -938,8 +954,8 @@ void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
938 + MULU16(_gray_info.width, y >> _PBLOCK_EXP); 954 + MULU16(_gray_info.width, y >> _PBLOCK_EXP);
939 ny = height - 1 + shift; 955 ny = height - 1 + shift;
940 956
941 mask = 0xFFu << (LCD_DEPTH * shift); 957 mask = 0xFFu << shift;
942 mask_bottom = 0xFFu >> (LCD_DEPTH * (~ny & (_PBLOCK-1))); 958 mask_bottom = 0xFFu >> (~ny & (_PBLOCK-1));
943 959
944 for (; ny >= _PBLOCK; ny -= _PBLOCK) 960 for (; ny >= _PBLOCK; ny -= _PBLOCK)
945 { 961 {
diff --git a/apps/plugins/lib/gray_scroll.c b/apps/plugins/lib/gray_scroll.c
index f7ace0e47c..341024a67e 100644
--- a/apps/plugins/lib/gray_scroll.c
+++ b/apps/plugins/lib/gray_scroll.c
@@ -294,7 +294,9 @@ void gray_ub_scroll_up(int count)
294 "extu.b r0,r1 \n" /* store data for next round */ 294 "extu.b r0,r1 \n" /* store data for next round */
295 295
296 ".su_shift6: \n" /* shift right by 0..7 bits */ 296 ".su_shift6: \n" /* shift right by 0..7 bits */
297 "shlr2 r0 \n" 297 "shll2 r0 \n"
298 "bra .su_shift0 \n"
299 "shlr8 r0 \n"
298 ".su_shift4: \n" 300 ".su_shift4: \n"
299 "shlr2 r0 \n" 301 "shlr2 r0 \n"
300 ".su_shift2: \n" 302 ".su_shift2: \n"
@@ -378,7 +380,7 @@ void gray_ub_scroll_up(int count)
378 [wide]"r"(_gray_info.width), 380 [wide]"r"(_gray_info.width),
379 [rows]"r"(_gray_info.bheight - shift), 381 [rows]"r"(_gray_info.bheight - shift),
380 [addr]"a"(_gray_info.plane_data + _gray_info.plane_size - blockshift), 382 [addr]"a"(_gray_info.plane_data + _gray_info.plane_size - blockshift),
381 [cnt] "d"(2 * count) 383 [cnt] "d"(count)
382 : /* clobbers */ 384 : /* clobbers */
383 "a0", "a1", "d0", "d1", "d2", "d3", "d4" 385 "a0", "a1", "d0", "d1", "d2", "d3", "d4"
384 ); 386 );
@@ -474,7 +476,9 @@ void gray_ub_scroll_down(int count)
474 "extu.b r0,r0 \n" /* extend unsigned */ 476 "extu.b r0,r0 \n" /* extend unsigned */
475 477
476 ".sd_shift6: \n" /* shift left by 0..7 bits */ 478 ".sd_shift6: \n" /* shift left by 0..7 bits */
477 "shll2 r0 \n" 479 "shll8 r0 \n"
480 "bra .sd_shift0 \n"
481 "shlr2 r0 \n"
478 ".sd_shift4: \n" 482 ".sd_shift4: \n"
479 "shll2 r0 \n" 483 "shll2 r0 \n"
480 ".sd_shift2: \n" 484 ".sd_shift2: \n"
@@ -557,7 +561,7 @@ void gray_ub_scroll_down(int count)
557 [rows]"r"(_gray_info.bheight - shift), 561 [rows]"r"(_gray_info.bheight - shift),
558 [psiz]"r"(_gray_info.plane_size), 562 [psiz]"r"(_gray_info.plane_size),
559 [addr]"a"(_gray_info.plane_data + blockshift), 563 [addr]"a"(_gray_info.plane_data + blockshift),
560 [cnt] "d"(2 * count) 564 [cnt] "d"(count)
561 : /* clobbers */ 565 : /* clobbers */
562 "a0", "a1", "d0", "d1", "d2", "d3", "d4" 566 "a0", "a1", "d0", "d1", "d2", "d3", "d4"
563 ); 567 );
diff --git a/apps/plugins/mandelbrot.c b/apps/plugins/mandelbrot.c
index d5fb0f2b04..88f48d3f2b 100644
--- a/apps/plugins/mandelbrot.c
+++ b/apps/plugins/mandelbrot.c
@@ -353,8 +353,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
353 353
354 /* initialize the grayscale buffer: 354 /* initialize the grayscale buffer:
355 * 8 bitplanes for 9 shades of gray.*/ 355 * 8 bitplanes for 9 shades of gray.*/
356 grayscales = gray_init(rb, gbuf, gbuf_size, false, LCD_WIDTH, 356 grayscales = gray_init(rb, gbuf, gbuf_size, false, LCD_WIDTH, LCD_HEIGHT/8,
357 (LCD_HEIGHT*LCD_DEPTH/8), 8, NULL) + 1; 357 8, NULL) + 1;
358 if (grayscales != 9) { 358 if (grayscales != 9) {
359 rb->snprintf(buff, sizeof(buff), "%d", grayscales); 359 rb->snprintf(buff, sizeof(buff), "%d", grayscales);
360 rb->lcd_puts(0, 1, buff); 360 rb->lcd_puts(0, 1, buff);