summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--firmware/drivers/lcd-h100.c31
8 files changed, 155 insertions, 96 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);
diff --git a/firmware/drivers/lcd-h100.c b/firmware/drivers/lcd-h100.c
index bfdceedc35..df08dde6fb 100644
--- a/firmware/drivers/lcd-h100.c
+++ b/firmware/drivers/lcd-h100.c
@@ -211,16 +211,41 @@ void lcd_init(void)
211void lcd_blit(const unsigned char* data, int x, int by, int width, 211void lcd_blit(const unsigned char* data, int x, int by, int width,
212 int bheight, int stride) 212 int bheight, int stride)
213{ 213{
214 /* Copy display bitmap to hardware */ 214 const unsigned char *src, *src_end;
215 unsigned char *dst_u, *dst_l;
216 unsigned char upper[LCD_WIDTH];
217 unsigned char lower[LCD_WIDTH];
218 unsigned int byte;
219
220 by *= 2;
221
215 while (bheight--) 222 while (bheight--)
216 { 223 {
224 src = data;
225 src_end = data + width;
226 dst_u = upper;
227 dst_l = lower;
228 do
229 {
230 byte = *src++;
231 *dst_u++ = dibits[byte & 0x0F];
232 byte >>= 4;
233 *dst_l++ = dibits[byte & 0x0F];
234 }
235 while (src < src_end);
236
217 lcd_write_command_ex(LCD_CNTL_PAGE, by++, -1); 237 lcd_write_command_ex(LCD_CNTL_PAGE, by++, -1);
218 lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1); 238 lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1);
239 lcd_write_command(LCD_CNTL_DATA_WRITE);
240 lcd_write_data(upper, width);
219 241
242 lcd_write_command_ex(LCD_CNTL_PAGE, by++, -1);
243 lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1);
220 lcd_write_command(LCD_CNTL_DATA_WRITE); 244 lcd_write_command(LCD_CNTL_DATA_WRITE);
221 lcd_write_data(data, width); 245 lcd_write_data(lower, width);
246
222 data += stride; 247 data += stride;
223 } 248 }
224} 249}
225 250
226 251