summaryrefslogtreecommitdiff
path: root/apps/plugins/lib/gray_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lib/gray_core.c')
-rw-r--r--apps/plugins/lib/gray_core.c132
1 files changed, 75 insertions, 57 deletions
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