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.c403
1 files changed, 357 insertions, 46 deletions
diff --git a/apps/plugins/lib/gray_core.c b/apps/plugins/lib/gray_core.c
index a9a3e7698f..679d52130d 100644
--- a/apps/plugins/lib/gray_core.c
+++ b/apps/plugins/lib/gray_core.c
@@ -11,7 +11,8 @@
11* Core & miscellaneous functions 11* Core & miscellaneous functions
12* 12*
13* This is a generic framework to display up to 33 shades of grey 13* This is a generic framework to display up to 33 shades of grey
14* on low-depth bitmap LCDs (Archos b&w, Iriver 4-grey) within plugins. 14* on low-depth bitmap LCDs (Archos b&w, Iriver 4-grey, iPod 4-grey)
15* within plugins.
15* 16*
16* Copyright (C) 2004-2006 Jens Arnold 17* Copyright (C) 2004-2006 Jens Arnold
17* 18*
@@ -28,9 +29,14 @@
28#ifdef HAVE_LCD_BITMAP 29#ifdef HAVE_LCD_BITMAP
29#include "gray.h" 30#include "gray.h"
30 31
32#ifdef CPU_PP
33#define NEED_BOOST
34#endif
35
31/* Global variables */ 36/* Global variables */
32struct plugin_api *_gray_rb = NULL; /* global api struct pointer */ 37struct plugin_api *_gray_rb = NULL; /* global api struct pointer */
33struct _gray_info _gray_info; /* global info structure */ 38struct _gray_info _gray_info; /* global info structure */
39
34#ifndef SIMULATOR 40#ifndef SIMULATOR
35short _gray_random_buffer; /* buffer for random number generator */ 41short _gray_random_buffer; /* buffer for random number generator */
36 42
@@ -106,6 +112,43 @@ static const unsigned char lcdlinear[256] = {
106 227, 228, 230, 232, 233, 235, 237, 239, 112 227, 228, 230, 232, 233, 235, 237, 239,
107 241, 243, 245, 247, 249, 251, 253, 255 113 241, 243, 245, 247, 249, 251, 253, 255
108}; 114};
115#elif (CONFIG_LCD == LCD_IPOD2BPP) || (CONFIG_LCD == LCD_IPODMINI)
116/* measured and interpolated curve for mini LCD */
117/* TODO: verify this curve on the fullsize greyscale LCD */
118static const unsigned char lcdlinear[256] = {
119 0, 3, 6, 8, 11, 14, 17, 19,
120 22, 24, 27, 29, 32, 34, 36, 38,
121 40, 42, 44, 45, 47, 48, 50, 51,
122 52, 54, 55, 56, 57, 58, 58, 59,
123 60, 61, 62, 62, 63, 64, 64, 65,
124 66, 66, 67, 67, 68, 68, 69, 69,
125 70, 70, 70, 71, 71, 71, 72, 72,
126 73, 73, 73, 74, 74, 74, 74, 75,
127 75, 75, 76, 76, 76, 77, 77, 77,
128 78, 78, 78, 79, 79, 79, 80, 80,
129 80, 80, 81, 81, 81, 82, 82, 82,
130 83, 83, 83, 84, 84, 84, 85, 85,
131 85, 85, 86, 86, 86, 87, 87, 87,
132 87, 88, 88, 88, 89, 89, 89, 89,
133 90, 90, 90, 91, 91, 91, 92, 92,
134 92, 93, 93, 93, 94, 94, 94, 95,
135 95, 96, 96, 96, 97, 97, 98, 98,
136 99, 99, 99, 100, 100, 101, 101, 102,
137 102, 103, 103, 104, 104, 105, 105, 106,
138 106, 107, 107, 108, 108, 109, 109, 110,
139 110, 111, 111, 112, 113, 113, 114, 114,
140 115, 115, 116, 117, 117, 118, 118, 119,
141 120, 120, 121, 122, 122, 123, 124, 124,
142 125, 126, 126, 127, 128, 128, 129, 130,
143 131, 131, 132, 133, 134, 134, 135, 136,
144 137, 138, 139, 140, 141, 142, 143, 144,
145 145, 146, 147, 148, 149, 150, 152, 153,
146 154, 156, 157, 159, 160, 162, 163, 165,
147 167, 168, 170, 172, 174, 176, 178, 180,
148 182, 184, 187, 189, 192, 194, 197, 200,
149 203, 206, 209, 212, 215, 219, 222, 226,
150 229, 233, 236, 240, 244, 248, 251, 255
151};
109#endif 152#endif
110#else /* SIMULATOR */ 153#else /* SIMULATOR */
111/* undo a (generic) PC display gamma of 2.0 to simulate target behaviour */ 154/* undo a (generic) PC display gamma of 2.0 to simulate target behaviour */
@@ -147,20 +190,22 @@ static const unsigned char lcdlinear[256] = {
147 190
148/* Prototypes */ 191/* Prototypes */
149static inline void _deferred_update(void) __attribute__ ((always_inline)); 192static inline void _deferred_update(void) __attribute__ ((always_inline));
193static int exp_s16p16(int x);
194static int log_s16p16(int x);
195static void gray_screendump_hook(int fd);
150#ifdef SIMULATOR 196#ifdef SIMULATOR
151static unsigned long _gray_get_pixel(int x, int y); 197static unsigned long _gray_get_pixel(int x, int y);
152#else 198#else
153static void _timer_isr(void); 199static void _timer_isr(void);
154#endif 200#endif
155static void gray_screendump_hook(int fd);
156 201
157/* Update LCD areas not covered by the greyscale overlay */ 202/* Update LCD areas not covered by the greyscale overlay */
158static inline void _deferred_update(void) 203static inline void _deferred_update(void)
159{ 204{
160 int x1 = MAX(_gray_info.x, 0); 205 int x1 = MAX(_gray_info.x, 0);
161 int x2 = MIN(_gray_info.x + _gray_info.width, LCD_WIDTH); 206 int x2 = MIN(_gray_info.x + _gray_info.width, LCD_WIDTH);
162 int y1 = MAX(_gray_info.by << _PBLOCK_EXP, 0); 207 int y1 = MAX(_gray_info.y, 0);
163 int y2 = MIN((_gray_info.by << _PBLOCK_EXP) + _gray_info.height, LCD_HEIGHT); 208 int y2 = MIN(_gray_info.y + _gray_info.height, LCD_HEIGHT);
164 209
165 if (y1 > 0) /* refresh part above overlay, full width */ 210 if (y1 > 0) /* refresh part above overlay, full width */
166 _gray_rb->lcd_update_rect(0, 0, LCD_WIDTH, y1); 211 _gray_rb->lcd_update_rect(0, 0, LCD_WIDTH, y1);
@@ -179,9 +224,15 @@ static inline void _deferred_update(void)
179/* Timer interrupt handler: display next bitplane */ 224/* Timer interrupt handler: display next bitplane */
180static void _timer_isr(void) 225static void _timer_isr(void)
181{ 226{
227#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
228 _gray_rb->lcd_blit(_gray_info.plane_data + MULU16(_gray_info.plane_size,
229 _gray_info.cur_plane), _gray_info.bx, _gray_info.y,
230 _gray_info.bwidth, _gray_info.height, _gray_info.bwidth);
231#else
182 _gray_rb->lcd_blit(_gray_info.plane_data + MULU16(_gray_info.plane_size, 232 _gray_rb->lcd_blit(_gray_info.plane_data + MULU16(_gray_info.plane_size,
183 _gray_info.cur_plane), _gray_info.x, _gray_info.by, 233 _gray_info.cur_plane), _gray_info.x, _gray_info.by,
184 _gray_info.width, _gray_info.bheight, _gray_info.width); 234 _gray_info.width, _gray_info.bheight, _gray_info.width);
235#endif
185 236
186 if (++_gray_info.cur_plane >= _gray_info.depth) 237 if (++_gray_info.cur_plane >= _gray_info.depth)
187 _gray_info.cur_plane = 0; 238 _gray_info.cur_plane = 0;
@@ -200,7 +251,7 @@ static int exp_s16p16(int x)
200 int t; 251 int t;
201 int y = 0x00010000; 252 int y = 0x00010000;
202 253
203 if (x < 0) x += 0xb1721, y >>= 16; 254 if (x < 0) x += 0xb1721, y >>= 16;
204 t = x - 0x58b91; if (t >= 0) x = t, y <<= 8; 255 t = x - 0x58b91; if (t >= 0) x = t, y <<= 8;
205 t = x - 0x2c5c8; if (t >= 0) x = t, y <<= 4; 256 t = x - 0x2c5c8; if (t >= 0) x = t, y <<= 4;
206 t = x - 0x162e4; if (t >= 0) x = t, y <<= 2; 257 t = x - 0x162e4; if (t >= 0) x = t, y <<= 2;
@@ -218,7 +269,7 @@ static int exp_s16p16(int x)
218} 269}
219 270
220/* fixed point log() */ 271/* fixed point log() */
221int log_s16p16(int x) 272static int log_s16p16(int x)
222{ 273{
223 int t; 274 int t;
224 int y = 0xa65af; 275 int y = 0xa65af;
@@ -252,7 +303,9 @@ int log_s16p16(int x)
252 memory. Unbuffered operation provides only a subset of 303 memory. Unbuffered operation provides only a subset of
253 drawing functions. (only gray_bitmap drawing and scrolling) 304 drawing functions. (only gray_bitmap drawing and scrolling)
254 width = width in pixels (1..LCD_WIDTH) 305 width = width in pixels (1..LCD_WIDTH)
255 bheight = height in LCD pixel-block units (8 pixels) (1..LCD_HEIGHT/8) 306 height = height in pixels (1..LCD_HEIGHT)
307 Note that depending on the target LCD, either height or
308 width are rounded up to a multiple of 8.
256 depth = number of bitplanes to use (1..32). 309 depth = number of bitplanes to use (1..32).
257 gamma = gamma value as s8p8 fixed point. gamma <= 0 means no 310 gamma = gamma value as s8p8 fixed point. gamma <= 0 means no
258 correction at all, i.e. no LCD linearisation as well. 311 correction at all, i.e. no LCD linearisation as well.
@@ -277,20 +330,21 @@ int log_s16p16(int x)
277 used. The total memory needed can be calculated as follows: 330 used. The total memory needed can be calculated as follows:
278 total_mem = 331 total_mem =
279 shades * sizeof(long) (bitpatterns) 332 shades * sizeof(long) (bitpatterns)
280 + (width * bheight) * depth (bitplane data) 333 + [horizontal_packing] ? (bitplane data)
334 ((width + 7) / 8) * height * depth : width * ((height + 7) / 8) * depth
281 + buffered ? (chunky front- & backbuffer) 335 + buffered ? (chunky front- & backbuffer)
282 (width * bheight * 8 * 2) : 0 336 (width * height * 2) : 0
283 + 0..3 (longword alignment) 337 + 0..3 (longword alignment)
284 338
285 The function tries to be as authentic as possible regarding memory usage on 339 The function tries to be as authentic as possible regarding memory usage on
286 the simulator, even if it doesn't use all of the allocated memory. There's 340 the simulator, even if it doesn't use all of the allocated memory. There's
287 one situation where it will consume more memory on the sim than on the 341 one situation where it will consume more memory on the sim than on the
288 target: if you're allocating a low depth (< 8) without buffering. */ 342 target: if you're allocating a low depth (< 8) without buffering. */
289int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, 343int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
290 bool buffered, int width, int bheight, int depth, int gamma, 344 bool buffered, int width, int height, int depth, int gamma,
291 long *buf_taken) 345 long *buf_taken)
292{ 346{
293 int possible_depth, i; 347 int possible_depth, bdim, i;
294 long plane_size, buftaken; 348 long plane_size, buftaken;
295 unsigned data; 349 unsigned data;
296#ifndef SIMULATOR 350#ifndef SIMULATOR
@@ -300,10 +354,18 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
300 _gray_rb = newrb; 354 _gray_rb = newrb;
301 355
302 if ((unsigned) width > LCD_WIDTH 356 if ((unsigned) width > LCD_WIDTH
303 || (unsigned) bheight > (LCD_HEIGHT/_PBLOCK) 357 || (unsigned) height > LCD_HEIGHT
304 || depth < 1) 358 || depth < 1)
305 return 0; 359 return 0;
306 360
361#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
362 bdim = (width + 7) >> 3;
363 width = bdim << 3;
364#else
365 bdim = (height + 7) >> 3;
366 height = bdim << 3;
367#endif
368
307 /* the buffer has to be long aligned */ 369 /* the buffer has to be long aligned */
308 buftaken = (-(long)gbuf) & 3; 370 buftaken = (-(long)gbuf) & 3;
309 gbuf += buftaken; 371 gbuf += buftaken;
@@ -311,7 +373,7 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
311 /* chunky front- & backbuffer */ 373 /* chunky front- & backbuffer */
312 if (buffered) 374 if (buffered)
313 { 375 {
314 plane_size = MULU16(width, bheight << _PBLOCK_EXP); 376 plane_size = MULU16(width, height);
315 buftaken += 2 * plane_size; 377 buftaken += 2 * plane_size;
316 if (buftaken > gbuf_size) 378 if (buftaken > gbuf_size)
317 return 0; 379 return 0;
@@ -324,7 +386,11 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
324 gbuf += plane_size; 386 gbuf += plane_size;
325 } 387 }
326 388
327 plane_size = MULU16(width, bheight); 389#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
390 plane_size = MULU16(bdim, height);
391#else
392 plane_size = MULU16(width, bdim);
393#endif
328 possible_depth = (gbuf_size - buftaken - sizeof(long)) 394 possible_depth = (gbuf_size - buftaken - sizeof(long))
329 / (plane_size + sizeof(long)); 395 / (plane_size + sizeof(long));
330 396
@@ -339,7 +405,7 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
339 { 405 {
340 long orig_size = depth * plane_size + (depth + 1) * sizeof(long); 406 long orig_size = depth * plane_size + (depth + 1) * sizeof(long);
341 407
342 plane_size = MULU16(width, bheight << _PBLOCK_EXP); 408 plane_size = MULU16(width, height);
343 if (plane_size > orig_size) 409 if (plane_size > orig_size)
344 { 410 {
345 buftaken += plane_size; 411 buftaken += plane_size;
@@ -357,10 +423,16 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
357 buftaken += depth * plane_size + (depth + 1) * sizeof(long); 423 buftaken += depth * plane_size + (depth + 1) * sizeof(long);
358 424
359 _gray_info.x = 0; 425 _gray_info.x = 0;
360 _gray_info.by = 0; 426 _gray_info.y = 0;
361 _gray_info.width = width; 427 _gray_info.width = width;
362 _gray_info.height = bheight << _PBLOCK_EXP; 428 _gray_info.height = height;
363 _gray_info.bheight = bheight; 429#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
430 _gray_info.bx = 0;
431 _gray_info.bwidth = bdim;
432#else
433 _gray_info.by = 0;
434 _gray_info.bheight = bdim;
435#endif
364 _gray_info.depth = depth; 436 _gray_info.depth = depth;
365 _gray_info.flags = 0; 437 _gray_info.flags = 0;
366#ifndef SIMULATOR 438#ifndef SIMULATOR
@@ -463,13 +535,20 @@ void gray_show(bool enable)
463 _gray_rb->sim_lcd_ex_init(_gray_info.depth + 1, _gray_get_pixel); 535 _gray_rb->sim_lcd_ex_init(_gray_info.depth + 1, _gray_get_pixel);
464 gray_update(); 536 gray_update();
465#else /* !SIMULATOR */ 537#else /* !SIMULATOR */
538#ifdef NEED_BOOST
539 _gray_rb->cpu_boost(true);
540#endif
466#if CONFIG_LCD == LCD_SSD1815 541#if CONFIG_LCD == LCD_SSD1815
467 _gray_rb->timer_register(1, NULL, TIMER_FREQ / 67, 1, _timer_isr); 542 _gray_rb->timer_register(1, NULL, TIMER_FREQ / 67, 1, _timer_isr);
468#elif CONFIG_LCD == LCD_S1D15E06 543#elif CONFIG_LCD == LCD_S1D15E06
469 _gray_rb->timer_register(1, NULL, TIMER_FREQ / 70, 1, _timer_isr); 544 _gray_rb->timer_register(1, NULL, TIMER_FREQ / 70, 1, _timer_isr);
545#elif CONFIG_LCD == LCD_IPOD2BPP
546 /* FIXME: verify value */
547 _gray_rb->timer_register(1, NULL, TIMER_FREQ / 40, 1, _timer_isr);
548#elif CONFIG_LCD == LCD_IPODMINI
549 _gray_rb->timer_register(1, NULL, TIMER_FREQ / 44, 1, _timer_isr);
470#elif CONFIG_LCD == LCD_IFP7XX 550#elif CONFIG_LCD == LCD_IFP7XX
471 /* TODO: implement for iFP */ 551 (void)_timer_isr; /* TODO: implement for iFP */
472 (void)_timer_isr;
473#endif /* CONFIG_LCD */ 552#endif /* CONFIG_LCD */
474#endif /* !SIMULATOR */ 553#endif /* !SIMULATOR */
475 _gray_rb->screen_dump_set_hook(gray_screendump_hook); 554 _gray_rb->screen_dump_set_hook(gray_screendump_hook);
@@ -480,6 +559,9 @@ void gray_show(bool enable)
480 _gray_rb->sim_lcd_ex_init(0, NULL); 559 _gray_rb->sim_lcd_ex_init(0, NULL);
481#else 560#else
482 _gray_rb->timer_unregister(); 561 _gray_rb->timer_unregister();
562#ifdef NEED_BOOST
563 _gray_rb->cpu_boost(false);
564#endif
483#endif 565#endif
484 _gray_info.flags &= ~_GRAY_RUNNING; 566 _gray_info.flags &= ~_GRAY_RUNNING;
485 _gray_rb->screen_dump_set_hook(NULL); 567 _gray_rb->screen_dump_set_hook(NULL);
@@ -492,9 +574,15 @@ void gray_show(bool enable)
492 Note that x and y are in LCD coordinates, not graybuffer coordinates! */ 574 Note that x and y are in LCD coordinates, not graybuffer coordinates! */
493static unsigned long _gray_get_pixel(int x, int y) 575static unsigned long _gray_get_pixel(int x, int y)
494{ 576{
577#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
578 return _gray_info.cur_buffer[MULU16(y - _gray_info.y, _gray_info.width)
579 + x - _gray_info.x]
580 + (1 << LCD_DEPTH);
581#else
495 return _gray_info.cur_buffer[MULU16(x - _gray_info.x, _gray_info.height) 582 return _gray_info.cur_buffer[MULU16(x - _gray_info.x, _gray_info.height)
496 + y - (_gray_info.by << _PBLOCK_EXP)] 583 + y - _gray_info.y]
497 + (1 << LCD_DEPTH); 584 + (1 << LCD_DEPTH);
585#endif
498} 586}
499 587
500/* Update a rectangular area of the greyscale overlay */ 588/* Update a rectangular area of the greyscale overlay */
@@ -506,7 +594,7 @@ void gray_update_rect(int x, int y, int width, int height)
506 height = _gray_info.height - y; 594 height = _gray_info.height - y;
507 595
508 x += _gray_info.x; 596 x += _gray_info.x;
509 y += _gray_info.by << _PBLOCK_EXP; 597 y += _gray_info.y;
510 598
511 if (x + width > LCD_WIDTH) 599 if (x + width > LCD_WIDTH)
512 width = LCD_WIDTH - x; 600 width = LCD_WIDTH - x;
@@ -517,6 +605,148 @@ void gray_update_rect(int x, int y, int width, int height)
517} 605}
518 606
519#else /* !SIMULATOR */ 607#else /* !SIMULATOR */
608
609#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
610
611/* Update a rectangular area of the greyscale overlay */
612void gray_update_rect(int x, int y, int width, int height)
613{
614 int xmax, bwidth;
615 long srcofs;
616 unsigned char *dst;
617
618 if ((width <= 0) || (height <= 0))
619 return; /* nothing to do */
620
621 /* The X coordinates have to work on whole pixel block columns */
622 xmax = (x + width - 1) >> 3;
623 x >>= 3;
624
625 if (y + height > _gray_info.height)
626 height = _gray_info.height - y;
627 if (xmax >= _gray_info.bwidth)
628 xmax = _gray_info.bwidth - 1;
629 bwidth = xmax - x + 1;
630
631 srcofs = MULU16(_gray_info.width, y) + (x << 3);
632 dst = _gray_info.plane_data + MULU16(_gray_info.bwidth, y) + x;
633
634 /* Copy specified rectangle bitmap to hardware */
635 for (; height > 0; height--)
636 {
637 long srcofs_row = srcofs;
638 unsigned char *dst_row = dst;
639 unsigned char *dst_end = dst_row + bwidth;
640
641 do
642 {
643 unsigned long pat_stack[8];
644 unsigned long *pat_ptr;
645 unsigned char *cbuf, *bbuf;
646 unsigned change;
647
648 cbuf = _gray_info.cur_buffer + srcofs_row;
649 bbuf = _gray_info.back_buffer + srcofs_row;
650
651#if 0 /* CPU specific asm versions will go here */
652#else /* C version, for reference*/
653 (void)pat_ptr;
654 /* check whether anything changed in the 8-pixel block */
655 change = *(uint32_t *)cbuf ^ *(uint32_t *)bbuf;
656 cbuf += sizeof(uint32_t);
657 bbuf += sizeof(uint32_t);
658 change |= *(uint32_t *)cbuf ^ *(uint32_t *)bbuf;
659
660 if (change != 0)
661 {
662 unsigned char *addr, *end;
663 unsigned mask = 0;
664 unsigned test = 1;
665 int i;
666
667 cbuf = _gray_info.cur_buffer + srcofs_row;
668 bbuf = _gray_info.back_buffer + srcofs_row;
669
670 /* precalculate the bit patterns with random shifts
671 * for all 8 pixels and put them on an extra "stack" */
672 for (i = 7; i >= 0; i--)
673 {
674 unsigned pat = 0;
675 unsigned char cur = *cbuf++;
676 unsigned char back = *bbuf;
677
678 *bbuf++ = cur;
679
680 mask <<= 1;
681 if (cur != back)
682 {
683 int shift;
684
685 pat = _gray_info.bitpattern[cur];
686
687 /* shift pattern pseudo-random, simple & fast PRNG */
688 _gray_random_buffer = 75 * _gray_random_buffer + 74;
689 shift = (_gray_random_buffer >> 8) & _gray_info.randmask;
690 if (shift >= _gray_info.depth)
691 shift -= _gray_info.depth;
692
693 pat = (pat << shift) | (pat >> (_gray_info.depth - shift));
694
695 mask |= 1;
696 }
697 pat_stack[i] = pat;
698 }
699
700 addr = dst_row;
701 end = addr + MULU16(_gray_info.depth, _gray_info.plane_size);
702
703 /* set the bits for all 8 pixels in all bytes according to the
704 * precalculated patterns on the pattern stack */
705 mask = (~mask & 0xff);
706 if (mask == 0)
707 {
708 do
709 {
710 unsigned data = 0;
711
712 for (i = 7; i >= 0; i--)
713 data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
714
715 *addr = data;
716 addr += _gray_info.plane_size;
717 test <<= 1;
718 }
719 while (addr < end);
720 }
721 else
722 {
723 do
724 {
725 unsigned data = 0;
726
727 for (i = 7; i >= 0; i--)
728 data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
729
730 *addr = (*addr & mask) | data;
731 addr += _gray_info.plane_size;
732 test <<= 1;
733 }
734 while (addr < end);
735 }
736
737 }
738#endif /* CONFIG_CPU */
739 srcofs_row += 8;
740 dst_row++;
741 }
742 while (dst_row < dst_end);
743
744 srcofs += _gray_info.width;
745 dst += _gray_info.bwidth;
746 }
747}
748#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
749
520/* Update a rectangular area of the greyscale overlay */ 750/* Update a rectangular area of the greyscale overlay */
521void gray_update_rect(int x, int y, int width, int height) 751void gray_update_rect(int x, int y, int width, int height)
522{ 752{
@@ -524,22 +754,22 @@ void gray_update_rect(int x, int y, int width, int height)
524 long srcofs; 754 long srcofs;
525 unsigned char *dst; 755 unsigned char *dst;
526 756
527 if (width <= 0) 757 if ((width <= 0) || (height <= 0))
528 return; /* nothing to do */ 758 return; /* nothing to do */
529 759
530 /* The Y coordinates have to work on whole pixel block rows */ 760 /* The Y coordinates have to work on whole pixel block rows */
531 ymax = (y + height - 1) >> _PBLOCK_EXP; 761 ymax = (y + height - 1) >> 3;
532 y >>= _PBLOCK_EXP; 762 y >>= 3;
533 763
534 if (x + width > _gray_info.width) 764 if (x + width > _gray_info.width)
535 width = _gray_info.width - x; 765 width = _gray_info.width - x;
536 if (ymax >= _gray_info.bheight) 766 if (ymax >= _gray_info.bheight)
537 ymax = _gray_info.bheight - 1; 767 ymax = _gray_info.bheight - 1;
538 768
539 srcofs = (y << _PBLOCK_EXP) + MULU16(_gray_info.height, x); 769 srcofs = (y << 3) + MULU16(_gray_info.height, x);
540 dst = _gray_info.plane_data + MULU16(_gray_info.width, y) + x; 770 dst = _gray_info.plane_data + MULU16(_gray_info.width, y) + x;
541 771
542 /* Copy specified rectange bitmap to hardware */ 772 /* Copy specified rectangle bitmap to hardware */
543 for (; y <= ymax; y++) 773 for (; y <= ymax; y++)
544 { 774 {
545 long srcofs_row = srcofs; 775 long srcofs_row = srcofs;
@@ -548,7 +778,6 @@ void gray_update_rect(int x, int y, int width, int height)
548 778
549 do 779 do
550 { 780 {
551#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
552 unsigned long pat_stack[8]; 781 unsigned long pat_stack[8];
553 unsigned long *pat_ptr; 782 unsigned long *pat_ptr;
554 unsigned char *cbuf, *bbuf; 783 unsigned char *cbuf, *bbuf;
@@ -557,6 +786,7 @@ void gray_update_rect(int x, int y, int width, int height)
557 cbuf = _gray_info.cur_buffer + srcofs_row; 786 cbuf = _gray_info.cur_buffer + srcofs_row;
558 bbuf = _gray_info.back_buffer + srcofs_row; 787 bbuf = _gray_info.back_buffer + srcofs_row;
559 788
789#if CONFIG_CPU == SH7034
560 asm volatile ( 790 asm volatile (
561 "mov.l @%[cbuf]+,r1 \n" 791 "mov.l @%[cbuf]+,r1 \n"
562 "mov.l @%[bbuf]+,r2 \n" 792 "mov.l @%[bbuf]+,r2 \n"
@@ -738,15 +968,7 @@ void gray_update_rect(int x, int y, int width, int height)
738 "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10" 968 "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10"
739 ); 969 );
740 } 970 }
741#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) 971#elif defined(CPU_COLDFIRE)
742 unsigned long pat_stack[8];
743 unsigned long *pat_ptr;
744 unsigned char *cbuf, *bbuf;
745 unsigned change;
746
747 cbuf = _gray_info.cur_buffer + srcofs_row;
748 bbuf = _gray_info.back_buffer + srcofs_row;
749
750 asm volatile ( 972 asm volatile (
751 "move.l (%[cbuf])+,%%d0 \n" 973 "move.l (%[cbuf])+,%%d0 \n"
752 "move.l (%[bbuf])+,%%d1 \n" 974 "move.l (%[bbuf])+,%%d1 \n"
@@ -924,16 +1146,105 @@ void gray_update_rect(int x, int y, int width, int height)
924 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1" 1146 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1"
925 ); 1147 );
926 } 1148 }
927#endif /* CONFIG_CPU, LCD_DEPTH */ 1149#else /* C version, for reference*/
1150#warning C version of gray_update_rect() used
1151 (void)pat_ptr;
1152 /* check whether anything changed in the 8-pixel block */
1153 change = *(uint32_t *)cbuf ^ *(uint32_t *)bbuf;
1154 cbuf += sizeof(uint32_t);
1155 bbuf += sizeof(uint32_t);
1156 change |= *(uint32_t *)cbuf ^ *(uint32_t *)bbuf;
1157
1158 if (change != 0)
1159 {
1160 unsigned char *addr, *end;
1161 unsigned mask = 0;
1162 unsigned test = 1;
1163 int i;
1164
1165 cbuf = _gray_info.cur_buffer + srcofs_row;
1166 bbuf = _gray_info.back_buffer + srcofs_row;
1167
1168 /* precalculate the bit patterns with random shifts
1169 * for all 8 pixels and put them on an extra "stack" */
1170 for (i = 0; i < 8; i++)
1171 {
1172 unsigned pat = 0;
1173 unsigned char cur = *cbuf++;
1174 unsigned char back = *bbuf;
1175
1176 *bbuf++ = cur;
1177
1178 if (cur != back)
1179 {
1180 int shift;
1181
1182 pat = _gray_info.bitpattern[cur];
1183
1184 /* shift pattern pseudo-random, simple & fast PRNG */
1185 _gray_random_buffer = 75 * _gray_random_buffer + 74;
1186 shift = (_gray_random_buffer >> 8) & _gray_info.randmask;
1187 if (shift >= _gray_info.depth)
1188 shift -= _gray_info.depth;
1189
1190 pat = (pat << shift) | (pat >> (_gray_info.depth - shift));
1191
1192 mask |= 0x100;
1193 }
1194 mask >>= 1;
1195 pat_stack[i] = pat;
1196 }
1197
1198 addr = dst_row;
1199 end = addr + MULU16(_gray_info.depth, _gray_info.plane_size);
1200
1201 /* set the bits for all 8 pixels in all bytes according to the
1202 * precalculated patterns on the pattern stack */
1203 mask = (~mask & 0xff);
1204 if (mask == 0)
1205 {
1206 do
1207 {
1208 unsigned data = 0;
1209
1210 for (i = 7; i >= 0; i--)
1211 data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
1212
1213 *addr = data;
1214 addr += _gray_info.plane_size;
1215 test <<= 1;
1216 }
1217 while (addr < end);
1218 }
1219 else
1220 {
1221 do
1222 {
1223 unsigned data = 0;
1224
1225 for (i = 7; i >= 0; i--)
1226 data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
1227
1228 *addr = (*addr & mask) | data;
1229 addr += _gray_info.plane_size;
1230 test <<= 1;
1231 }
1232 while (addr < end);
1233 }
1234
1235 }
1236#endif /* CONFIG_CPU */
928 srcofs_row += _gray_info.height; 1237 srcofs_row += _gray_info.height;
929 dst_row++; 1238 dst_row++;
930 } 1239 }
931 while (dst_row < dst_end); 1240 while (dst_row < dst_end);
932 1241
933 srcofs += _PBLOCK; 1242 srcofs += 8;
934 dst += _gray_info.width; 1243 dst += _gray_info.width;
935 } 1244 }
936} 1245}
1246#endif /* LCD_PIXELFORMAT */
1247
937#endif /* !SIMULATOR */ 1248#endif /* !SIMULATOR */
938 1249
939/* Update the whole greyscale overlay */ 1250/* Update the whole greyscale overlay */
@@ -1047,10 +1358,10 @@ static void gray_screendump_hook(int fd)
1047 { 1358 {
1048 _gray_rb->memset(linebuf, 0, BMP_LINESIZE); 1359 _gray_rb->memset(linebuf, 0, BMP_LINESIZE);
1049 1360
1050 gy = y - (_gray_info.by << _PBLOCK_EXP); 1361 gy = y - _gray_info.y;
1051#if LCD_DEPTH == 1 1362#if LCD_DEPTH == 1
1052 mask = 1 << (y & (_PBLOCK-1)); 1363 mask = 1 << (y & 7);
1053 by = y >> _PBLOCK_EXP; 1364 by = y >> 3;
1054 lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by); 1365 lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by);
1055 1366
1056 if ((unsigned) gy < (unsigned) _gray_info.height) 1367 if ((unsigned) gy < (unsigned) _gray_info.height)
@@ -1058,7 +1369,7 @@ static void gray_screendump_hook(int fd)
1058 /* line contains greyscale (and maybe b&w) graphics */ 1369 /* line contains greyscale (and maybe b&w) graphics */
1059#ifndef SIMULATOR 1370#ifndef SIMULATOR
1060 unsigned char *grayptr = _gray_info.plane_data 1371 unsigned char *grayptr = _gray_info.plane_data
1061 + MULU16(_gray_info.width, gy >> _PBLOCK_EXP); 1372 + MULU16(_gray_info.width, gy >> 3);
1062#endif 1373#endif
1063 1374
1064 for (x = 0; x < LCD_WIDTH; x++) 1375 for (x = 0; x < LCD_WIDTH; x++)
@@ -1108,8 +1419,8 @@ static void gray_screendump_hook(int fd)
1108 (void)mask; 1419 (void)mask;
1109#else 1420#else
1110 unsigned char *grayptr = _gray_info.plane_data 1421 unsigned char *grayptr = _gray_info.plane_data
1111 + MULU16(_gray_info.width, gy >> _PBLOCK_EXP); 1422 + MULU16(_gray_info.width, gy >> 3);
1112 mask = 1 << (gy & (_PBLOCK-1)); 1423 mask = 1 << (gy & 7);
1113#endif 1424#endif
1114 1425
1115 for (x = 0; x < LCD_WIDTH; x++) 1426 for (x = 0; x < LCD_WIDTH; x++)