diff options
Diffstat (limited to 'apps/plugins/lib/gray_core.c')
-rw-r--r-- | apps/plugins/lib/gray_core.c | 403 |
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 */ |
32 | struct plugin_api *_gray_rb = NULL; /* global api struct pointer */ | 37 | struct plugin_api *_gray_rb = NULL; /* global api struct pointer */ |
33 | struct _gray_info _gray_info; /* global info structure */ | 38 | struct _gray_info _gray_info; /* global info structure */ |
39 | |||
34 | #ifndef SIMULATOR | 40 | #ifndef SIMULATOR |
35 | short _gray_random_buffer; /* buffer for random number generator */ | 41 | short _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 */ | ||
118 | static 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 */ |
149 | static inline void _deferred_update(void) __attribute__ ((always_inline)); | 192 | static inline void _deferred_update(void) __attribute__ ((always_inline)); |
193 | static int exp_s16p16(int x); | ||
194 | static int log_s16p16(int x); | ||
195 | static void gray_screendump_hook(int fd); | ||
150 | #ifdef SIMULATOR | 196 | #ifdef SIMULATOR |
151 | static unsigned long _gray_get_pixel(int x, int y); | 197 | static unsigned long _gray_get_pixel(int x, int y); |
152 | #else | 198 | #else |
153 | static void _timer_isr(void); | 199 | static void _timer_isr(void); |
154 | #endif | 200 | #endif |
155 | static 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 */ |
158 | static inline void _deferred_update(void) | 203 | static 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 */ |
180 | static void _timer_isr(void) | 225 | static 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() */ |
221 | int log_s16p16(int x) | 272 | static 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. */ |
289 | int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, | 343 | int 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! */ |
493 | static unsigned long _gray_get_pixel(int x, int y) | 575 | static 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 */ | ||
612 | void 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 */ |
521 | void gray_update_rect(int x, int y, int width, int height) | 751 | void 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++) |