1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2004 Matthias Wientapper
11 * Heavily extended 2005 Jens Arnold
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
25 #ifdef HAVE_LCD_BITMAP
31 /* variable button definitions */
32 #if CONFIG_KEYPAD == RECORDER_PAD
33 #define MANDELBROT_QUIT BUTTON_OFF
34 #define MANDELBROT_UP BUTTON_UP
35 #define MANDELBROT_DOWN BUTTON_DOWN
36 #define MANDELBROT_LEFT BUTTON_LEFT
37 #define MANDELBROT_RIGHT BUTTON_RIGHT
38 #define MANDELBROT_ZOOM_IN BUTTON_PLAY
39 #define MANDELBROT_ZOOM_OUT BUTTON_ON
40 #define MANDELBROT_MAXITER_INC BUTTON_F2
41 #define MANDELBROT_MAXITER_DEC BUTTON_F1
42 #define MANDELBROT_RESET BUTTON_F3
44 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
45 #define MANDELBROT_QUIT BUTTON_OFF
46 #define MANDELBROT_UP BUTTON_UP
47 #define MANDELBROT_DOWN BUTTON_DOWN
48 #define MANDELBROT_LEFT BUTTON_LEFT
49 #define MANDELBROT_RIGHT BUTTON_RIGHT
50 #define MANDELBROT_ZOOM_IN BUTTON_SELECT
51 #define MANDELBROT_ZOOM_OUT BUTTON_ON
52 #define MANDELBROT_MAXITER_INC BUTTON_F2
53 #define MANDELBROT_MAXITER_DEC BUTTON_F1
54 #define MANDELBROT_RESET BUTTON_F3
56 #elif CONFIG_KEYPAD == ONDIO_PAD
57 #define MANDELBROT_QUIT BUTTON_OFF
58 #define MANDELBROT_UP BUTTON_UP
59 #define MANDELBROT_DOWN BUTTON_DOWN
60 #define MANDELBROT_LEFT BUTTON_LEFT
61 #define MANDELBROT_RIGHT BUTTON_RIGHT
62 #define MANDELBROT_ZOOM_IN_PRE BUTTON_MENU
63 #define MANDELBROT_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
64 #define MANDELBROT_ZOOM_IN2 (BUTTON_MENU | BUTTON_UP)
65 #define MANDELBROT_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
66 #define MANDELBROT_MAXITER_INC (BUTTON_MENU | BUTTON_RIGHT)
67 #define MANDELBROT_MAXITER_DEC (BUTTON_MENU | BUTTON_LEFT)
68 #define MANDELBROT_RESET (BUTTON_MENU | BUTTON_OFF)
70 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
71 (CONFIG_KEYPAD == IRIVER_H300_PAD)
72 #define MANDELBROT_QUIT BUTTON_OFF
73 #define MANDELBROT_UP BUTTON_UP
74 #define MANDELBROT_DOWN BUTTON_DOWN
75 #define MANDELBROT_LEFT BUTTON_LEFT
76 #define MANDELBROT_RIGHT BUTTON_RIGHT
77 #define MANDELBROT_ZOOM_IN BUTTON_SELECT
78 #define MANDELBROT_ZOOM_OUT BUTTON_MODE
79 #define MANDELBROT_MAXITER_INC (BUTTON_ON | BUTTON_RIGHT)
80 #define MANDELBROT_MAXITER_DEC (BUTTON_ON | BUTTON_LEFT)
81 #define MANDELBROT_RESET BUTTON_REC
83 #define MANDELBROT_RC_QUIT BUTTON_RC_STOP
85 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
86 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
87 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
88 #define MANDELBROT_QUIT (BUTTON_SELECT | BUTTON_MENU)
89 #define MANDELBROT_UP BUTTON_MENU
90 #define MANDELBROT_DOWN BUTTON_PLAY
91 #define MANDELBROT_LEFT BUTTON_LEFT
92 #define MANDELBROT_RIGHT BUTTON_RIGHT
93 #define MANDELBROT_ZOOM_IN BUTTON_SCROLL_FWD
94 #define MANDELBROT_ZOOM_OUT BUTTON_SCROLL_BACK
95 #define MANDELBROT_MAXITER_INC (BUTTON_SELECT | BUTTON_RIGHT)
96 #define MANDELBROT_MAXITER_DEC (BUTTON_SELECT | BUTTON_LEFT)
97 #define MANDELBROT_RESET (BUTTON_SELECT | BUTTON_PLAY)
99 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
100 #define MANDELBROT_QUIT BUTTON_POWER
101 #define MANDELBROT_UP BUTTON_UP
102 #define MANDELBROT_DOWN BUTTON_DOWN
103 #define MANDELBROT_LEFT BUTTON_LEFT
104 #define MANDELBROT_RIGHT BUTTON_RIGHT
105 #define MANDELBROT_ZOOM_IN_PRE BUTTON_SELECT
106 #define MANDELBROT_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
107 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_SELECT
108 #define MANDELBROT_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
109 #define MANDELBROT_MAXITER_INC_PRE BUTTON_PLAY
110 #define MANDELBROT_MAXITER_INC (BUTTON_PLAY | BUTTON_REL)
111 #define MANDELBROT_MAXITER_DEC_PRE BUTTON_PLAY
112 #define MANDELBROT_MAXITER_DEC (BUTTON_PLAY | BUTTON_REPEAT)
113 #define MANDELBROT_RESET BUTTON_REC
115 #elif CONFIG_KEYPAD == GIGABEAT_PAD
116 #define MANDELBROT_QUIT BUTTON_POWER
117 #define MANDELBROT_UP BUTTON_UP
118 #define MANDELBROT_DOWN BUTTON_DOWN
119 #define MANDELBROT_LEFT BUTTON_LEFT
120 #define MANDELBROT_RIGHT BUTTON_RIGHT
121 #define MANDELBROT_ZOOM_IN_PRE BUTTON_SELECT
122 #define MANDELBROT_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
123 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_SELECT
124 #define MANDELBROT_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
125 #define MANDELBROT_MAXITER_INC BUTTON_VOL_UP
126 #define MANDELBROT_MAXITER_DEC BUTTON_VOL_DOWN
127 #define MANDELBROT_RESET BUTTON_A
129 #elif CONFIG_KEYPAD == SANSA_E200_PAD
130 #define MANDELBROT_QUIT BUTTON_POWER
131 #define MANDELBROT_UP BUTTON_UP
132 #define MANDELBROT_DOWN BUTTON_DOWN
133 #define MANDELBROT_LEFT BUTTON_LEFT
134 #define MANDELBROT_RIGHT BUTTON_RIGHT
135 #define MANDELBROT_ZOOM_IN BUTTON_SCROLL_FWD
136 #define MANDELBROT_ZOOM_OUT BUTTON_SCROLL_BACK
137 #define MANDELBROT_MAXITER_INC (BUTTON_SELECT | BUTTON_RIGHT)
138 #define MANDELBROT_MAXITER_DEC (BUTTON_SELECT | BUTTON_LEFT)
139 #define MANDELBROT_RESET BUTTON_REC
141 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
142 #define MANDELBROT_QUIT (BUTTON_HOME|BUTTON_REPEAT)
143 #define MANDELBROT_UP BUTTON_UP
144 #define MANDELBROT_DOWN BUTTON_DOWN
145 #define MANDELBROT_LEFT BUTTON_LEFT
146 #define MANDELBROT_RIGHT BUTTON_RIGHT
147 #define MANDELBROT_ZOOM_IN BUTTON_SCROLL_FWD
148 #define MANDELBROT_ZOOM_OUT BUTTON_SCROLL_BACK
149 #define MANDELBROT_MAXITER_INC (BUTTON_SELECT | BUTTON_RIGHT)
150 #define MANDELBROT_MAXITER_DEC (BUTTON_SELECT | BUTTON_LEFT)
151 #define MANDELBROT_RESET (BUTTON_SELECT | BUTTON_REPEAT)
153 #elif CONFIG_KEYPAD == SANSA_C200_PAD
154 #define MANDELBROT_QUIT BUTTON_POWER
155 #define MANDELBROT_UP BUTTON_UP
156 #define MANDELBROT_DOWN BUTTON_DOWN
157 #define MANDELBROT_LEFT BUTTON_LEFT
158 #define MANDELBROT_RIGHT BUTTON_RIGHT
159 #define MANDELBROT_ZOOM_IN BUTTON_VOL_UP
160 #define MANDELBROT_ZOOM_OUT BUTTON_VOL_DOWN
161 #define MANDELBROT_MAXITER_INC (BUTTON_SELECT | BUTTON_RIGHT)
162 #define MANDELBROT_MAXITER_DEC (BUTTON_SELECT | BUTTON_LEFT)
163 #define MANDELBROT_RESET BUTTON_REC
165 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
166 #define MANDELBROT_QUIT BUTTON_POWER
167 #define MANDELBROT_UP BUTTON_UP
168 #define MANDELBROT_DOWN BUTTON_DOWN
169 #define MANDELBROT_LEFT BUTTON_LEFT
170 #define MANDELBROT_RIGHT BUTTON_RIGHT
171 #define MANDELBROT_ZOOM_IN BUTTON_VOL_UP
172 #define MANDELBROT_ZOOM_OUT BUTTON_VOL_DOWN
173 #define MANDELBROT_MAXITER_INC (BUTTON_SELECT | BUTTON_RIGHT)
174 #define MANDELBROT_MAXITER_DEC (BUTTON_SELECT | BUTTON_LEFT)
175 #define MANDELBROT_RESET BUTTON_HOME
177 #elif CONFIG_KEYPAD == SANSA_M200_PAD
178 #define MANDELBROT_QUIT BUTTON_POWER
179 #define MANDELBROT_UP BUTTON_UP
180 #define MANDELBROT_DOWN BUTTON_DOWN
181 #define MANDELBROT_LEFT BUTTON_LEFT
182 #define MANDELBROT_RIGHT BUTTON_RIGHT
183 #define MANDELBROT_ZOOM_IN BUTTON_VOL_UP
184 #define MANDELBROT_ZOOM_OUT BUTTON_VOL_DOWN
185 #define MANDELBROT_MAXITER_INC (BUTTON_SELECT | BUTTON_RIGHT)
186 #define MANDELBROT_MAXITER_DEC (BUTTON_SELECT | BUTTON_LEFT)
187 #define MANDELBROT_RESET (BUTTON_SELECT | BUTTON_UP)
189 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
190 #define MANDELBROT_QUIT BUTTON_POWER
191 #define MANDELBROT_UP BUTTON_SCROLL_UP
192 #define MANDELBROT_DOWN BUTTON_SCROLL_DOWN
193 #define MANDELBROT_LEFT BUTTON_LEFT
194 #define MANDELBROT_RIGHT BUTTON_RIGHT
195 #define MANDELBROT_ZOOM_IN_PRE BUTTON_PLAY
196 #define MANDELBROT_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
197 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_PLAY
198 #define MANDELBROT_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
199 #define MANDELBROT_MAXITER_INC BUTTON_FF
200 #define MANDELBROT_MAXITER_DEC BUTTON_REW
201 #define MANDELBROT_RESET (BUTTON_PLAY | BUTTON_REW)
203 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
204 #define MANDELBROT_QUIT BUTTON_EQ
205 #define MANDELBROT_UP BUTTON_UP
206 #define MANDELBROT_DOWN BUTTON_DOWN
207 #define MANDELBROT_LEFT BUTTON_LEFT
208 #define MANDELBROT_RIGHT BUTTON_RIGHT
209 #define MANDELBROT_ZOOM_IN_PRE BUTTON_SELECT
210 #define MANDELBROT_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
211 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_SELECT
212 #define MANDELBROT_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
213 #define MANDELBROT_MAXITER_INC (BUTTON_PLAY | BUTTON_RIGHT)
214 #define MANDELBROT_MAXITER_DEC (BUTTON_PLAY | BUTTON_LEFT)
215 #define MANDELBROT_RESET BUTTON_MODE
217 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
218 #define MANDELBROT_QUIT BUTTON_BACK
219 #define MANDELBROT_UP BUTTON_UP
220 #define MANDELBROT_DOWN BUTTON_DOWN
221 #define MANDELBROT_LEFT BUTTON_LEFT
222 #define MANDELBROT_RIGHT BUTTON_RIGHT
223 #define MANDELBROT_ZOOM_IN BUTTON_VOL_UP
224 #define MANDELBROT_ZOOM_OUT BUTTON_VOL_DOWN
225 #define MANDELBROT_MAXITER_INC BUTTON_PREV
226 #define MANDELBROT_MAXITER_DEC BUTTON_NEXT
227 #define MANDELBROT_RESET BUTTON_MENU
229 #elif CONFIG_KEYPAD == MROBE100_PAD
230 #define MANDELBROT_QUIT BUTTON_POWER
231 #define MANDELBROT_UP BUTTON_UP
232 #define MANDELBROT_DOWN BUTTON_DOWN
233 #define MANDELBROT_LEFT BUTTON_LEFT
234 #define MANDELBROT_RIGHT BUTTON_RIGHT
235 #define MANDELBROT_ZOOM_IN_PRE BUTTON_SELECT
236 #define MANDELBROT_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
237 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_SELECT
238 #define MANDELBROT_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
239 #define MANDELBROT_MAXITER_INC BUTTON_MENU
240 #define MANDELBROT_MAXITER_DEC BUTTON_PLAY
241 #define MANDELBROT_RESET BUTTON_DISPLAY
243 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
244 #define MANDELBROT_QUIT BUTTON_RC_REC
245 #define MANDELBROT_UP BUTTON_RC_VOL_UP
246 #define MANDELBROT_DOWN BUTTON_RC_VOL_DOWN
247 #define MANDELBROT_LEFT BUTTON_RC_REW
248 #define MANDELBROT_RIGHT BUTTON_RC_FF
249 #define MANDELBROT_ZOOM_IN_PRE BUTTON_RC_PLAY
250 #define MANDELBROT_ZOOM_IN (BUTTON_RC_PLAY | BUTTON_REL)
251 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_RC_PLAY
252 #define MANDELBROT_ZOOM_OUT (BUTTON_RC_PLAY | BUTTON_REPEAT)
253 #define MANDELBROT_MAXITER_INC_PRE BUTTON_RC_MODE
254 #define MANDELBROT_MAXITER_INC (BUTTON_RC_MODE|BUTTON_REL)
255 #define MANDELBROT_MAXITER_DEC_PRE BUTTON_RC_MODE
256 #define MANDELBROT_MAXITER_DEC (BUTTON_RC_MODE|BUTTON_REPEAT)
257 #define MANDELBROT_RESET BUTTON_RC_MENU
259 #elif CONFIG_KEYPAD == COWOND2_PAD
260 #define MANDELBROT_QUIT BUTTON_POWER
262 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
263 #define MANDELBROT_QUIT BUTTON_BACK
264 #define MANDELBROT_UP BUTTON_UP
265 #define MANDELBROT_DOWN BUTTON_DOWN
266 #define MANDELBROT_LEFT BUTTON_LEFT
267 #define MANDELBROT_RIGHT BUTTON_RIGHT
268 #define MANDELBROT_ZOOM_IN BUTTON_PLAY
269 #define MANDELBROT_ZOOM_OUT BUTTON_MENU
270 #define MANDELBROT_MAXITER_INC (BUTTON_UP | BUTTON_CUSTOM)
271 #define MANDELBROT_MAXITER_DEC (BUTTON_DOWN | BUTTON_CUSTOM)
272 #define MANDELBROT_RESET BUTTON_SELECT
274 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
275 #define MANDELBROT_QUIT BUTTON_POWER
276 #define MANDELBROT_UP BUTTON_UP
277 #define MANDELBROT_DOWN BUTTON_DOWN
278 #define MANDELBROT_LEFT BUTTON_LEFT
279 #define MANDELBROT_RIGHT BUTTON_RIGHT
280 #define MANDELBROT_ZOOM_IN BUTTON_VIEW
281 #define MANDELBROT_ZOOM_OUT BUTTON_PLAYLIST
282 #define MANDELBROT_MAXITER_INC BUTTON_VOL_UP
283 #define MANDELBROT_MAXITER_DEC BUTTON_VOL_DOWN
284 #define MANDELBROT_RESET BUTTON_MENU
286 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
287 #define MANDELBROT_QUIT BUTTON_POWER
288 #define MANDELBROT_UP BUTTON_UP
289 #define MANDELBROT_DOWN BUTTON_DOWN
290 #define MANDELBROT_LEFT BUTTON_PREV
291 #define MANDELBROT_RIGHT BUTTON_NEXT
292 #define MANDELBROT_ZOOM_IN BUTTON_RIGHT
293 #define MANDELBROT_ZOOM_OUT BUTTON_LEFT
294 #define MANDELBROT_MAXITER_INC BUTTON_VOL_UP
295 #define MANDELBROT_MAXITER_DEV BUTTON_VOL_DOWN
296 #define MANDELBROT_RESET BUTTON_MENU
298 #elif CONFIG_KEYPAD == ONDAVX747_PAD || CONFIG_KEYPAD == MROBE500_PAD
299 #define MANDELBROT_QUIT BUTTON_POWER
301 #elif CONFIG_KEYPAD == ONDAVX777_PAD
302 #define MANDELBROT_QUIT BUTTON_POWER
304 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
305 #define MANDELBROT_QUIT BUTTON_REC
306 #define MANDELBROT_UP BUTTON_UP
307 #define MANDELBROT_DOWN BUTTON_DOWN
308 #define MANDELBROT_LEFT BUTTON_LEFT
309 #define MANDELBROT_RIGHT BUTTON_RIGHT
310 #define MANDELBROT_ZOOM_IN_PRE (BUTTON_FFWD | BUTTON_UP)
311 #define MANDELBROT_ZOOM_IN (BUTTON_REW | BUTTON_UP)
312 #define MANDELBROT_ZOOM_OUT_PRE (BUTTON_FFWD | BUTTON_DOWN)
313 #define MANDELBROT_ZOOM_OUT (BUTTON_REW | BUTTON_DOWN)
314 #define MANDELBROT_MAXITER_INC (BUTTON_PLAY | BUTTON_UP)
315 #define MANDELBROT_MAXITER_DEC (BUTTON_FFWD | BUTTON_DOWN)
316 #define MANDELBROT_RESET (BUTTON_PLAY | BUTTON_RIGHT)
319 #error No keymap defined!
322 #ifdef HAVE_TOUCHSCREEN
323 #ifndef MANDELBROT_UP
324 #define MANDELBROT_UP BUTTON_TOPMIDDLE
326 #ifndef MANDELBROT_DOWN
327 #define MANDELBROT_DOWN BUTTON_BOTTOMMIDDLE
329 #ifndef MANDELBROT_LEFT
330 #define MANDELBROT_LEFT BUTTON_MIDLEFT
332 #ifndef MANDELBROT_RIGHT
333 #define MANDELBROT_RIGHT BUTTON_MIDRIGHT
335 #ifndef MANDELBROT_ZOOM_IN_PRE
336 #define MANDELBROT_ZOOM_IN_PRE BUTTON_TOPRIGHT
338 #ifndef MANDELBROT_ZOOM_IN
339 #define MANDELBROT_ZOOM_IN (BUTTON_TOPRIGHT | BUTTON_REL)
341 #ifndef MANDELBROT_ZOOM_OUT_PRE
342 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_TOPLEFT
344 #ifndef MANDELBROT_ZOOM_OUT
345 #define MANDELBROT_ZOOM_OUT (BUTTON_TOPLEFT | BUTTON_REL)
347 #ifndef MANDELBROT_MAXITER_INC
348 #define MANDELBROT_MAXITER_INC BUTTON_BOTTOMRIGHT
350 #ifndef MANDELBROT_MAXITER_DEC
351 #define MANDELBROT_MAXITER_DEC BUTTON_BOTTOMLEFT
353 #ifndef MANDELBROT_RESET
354 #define MANDELBROT_RESET BUTTON_CENTER
360 #define MYLCD(fn) grey_ub_ ## fn
361 #define MYLCD_UPDATE()
362 #define MYXLCD(fn) grey_ub_ ## fn
364 #define UPDATE_FREQ (HZ/50)
365 #define MYLCD(fn) rb->lcd_ ## fn
366 #define MYLCD_UPDATE() rb->lcd_update();
367 #define MYXLCD(fn) xlcd_ ## fn
370 /* Fixed point format s5.26: sign, 5 bits integer part, 26 bits fractional part */
380 static int px_min
= 0;
381 static int px_max
= LCD_WIDTH
;
382 static int py_min
= 0;
383 static int py_max
= LCD_HEIGHT
;
385 static int step_log2
;
386 static unsigned max_iter
;
390 static unsigned char *gbuf
;
391 static size_t gbuf_size
= 0;
392 static unsigned char imgbuffer
[LCD_HEIGHT
];
394 static fb_data imgbuffer
[LCD_HEIGHT
];
397 /* 8 entries cyclical, last entry is black (convergence) */
398 #ifdef HAVE_LCD_COLOR
399 static const fb_data color
[9] = {
400 LCD_RGBPACK(255, 0, 159), LCD_RGBPACK(159, 0, 255), LCD_RGBPACK(0, 0, 255),
401 LCD_RGBPACK(0, 159, 255), LCD_RGBPACK(0, 255, 128), LCD_RGBPACK(128, 255, 0),
402 LCD_RGBPACK(255, 191, 0), LCD_RGBPACK(255, 0, 0), LCD_RGBPACK(0, 0, 0)
404 #else /* greyscale */
405 static const unsigned char color
[9] = {
406 255, 223, 191, 159, 128, 96, 64, 32, 0
410 #if CONFIG_CPU == SH7034
412 #define MULS16_ASR10(a, b) muls16_asr10(a, b)
413 static inline short muls16_asr10(short a
, short b
)
430 #define MULS32_ASR26(a, b) muls32_asr26(a, b)
431 static inline long muls32_asr26(long a
, long b
)
435 /* Signed 32bit * 32bit -> 64bit multiplication.
436 Notation: xxab * xxcd, where each letter represents 16 bits.
437 xx is the 64 bit sign extension. */
438 "swap.w %[a],%[t1] \n" /* t1 = ba */
439 "mulu %[t1],%[b] \n" /* a * d */
440 "swap.w %[b],%[t3] \n" /* t3 = dc */
441 "sts macl,%[t2] \n" /* t2 = a * d */
442 "mulu %[t1],%[t3] \n" /* a * c */
443 "sts macl,%[r] \n" /* hi = a * c */
444 "mulu %[a],%[t3] \n" /* b * c */
446 "sts macl,%[t3] \n" /* t3 = b * c */
447 "addc %[t2],%[t3] \n" /* t3 += t2, carry -> t2 */
449 "mulu %[a],%[b] \n" /* b * d */
450 "mov %[t3],%[t1] \n" /* t1t3 = t2t3 << 16 */
451 "xtrct %[t2],%[t1] \n"
453 "sts macl,%[t2] \n" /* lo = b * d */
454 "clrt \n" /* hi.lo += t1t3 */
455 "addc %[t3],%[t2] \n"
457 "cmp/pz %[a] \n" /* ab >= 0 ? */
459 "sub %[b],%[r] \n" /* no: hi -= cd (sign extension of ab is -1) */
461 "cmp/pz %[b] \n" /* cd >= 0 ? */
463 "sub %[a],%[r] \n" /* no: hi -= ab (sign extension of cd is -1) */
465 /* Shift right by 26 and return low 32 bits */
466 "shll2 %[r] \n" /* hi <<= 6 */
469 "shlr16 %[t2] \n" /* (unsigned)lo >>= 26 */
472 "or %[t2],%[r] \n" /* combine result */
485 #elif defined CPU_COLDFIRE
487 #define MULS16_ASR10(a, b) muls16_asr10(a, b)
488 static inline short muls16_asr10(short a
, short b
)
491 "muls.w %[a],%[b] \n"
502 /* Needs the EMAC initialised to fractional mode w/o rounding and saturation */
503 #define MULS32_INIT() coldfire_set_macsr(EMAC_FRACTIONAL)
504 #define MULS32_ASR26(a, b) muls32_asr26(a, b)
505 static inline long muls32_asr26(long a
, long b
)
509 "mac.l %[a], %[b], %%acc0 \n" /* multiply */
510 "move.l %%accext01, %[t1] \n" /* get low part */
511 "movclr.l %%acc0, %[r] \n" /* get high part */
512 "asl.l #5, %[r] \n" /* hi <<= 5, plus one free */
513 "lsr.l #3, %[t1] \n" /* lo >>= 3 */
514 "and.l #0x1f, %[t1] \n" /* mask out unrelated bits */
515 "or.l %[t1], %[r] \n" /* combine result */
526 #elif defined CPU_ARM
528 #define MULS32_ASR26(a, b) muls32_asr26(a, b)
529 static inline long muls32_asr26(long a
, long b
)
533 "smull %[r], %[t1], %[a], %[b] \n"
534 "mov %[r], %[r], lsr #26 \n"
535 "orr %[r], %[r], %[t1], lsl #6 \n"
550 #define MULS16_ASR10(a, b) ((short)(((long)(a) * (long)(b)) >> 10))
553 #define MULS32_ASR26(a, b) ((long)(((long long)(a) * (long long)(b)) >> 26))
556 #define MULS32_INIT()
559 int ilog2_fp(long value
) /* calculate integer log2(value_fp_6.26) */
565 } else if (value
> (1L<<26)) {
566 while (value
>= (2L<<26)) {
571 while (value
< (1L<<26)) {
579 void recalc_parameters(void)
581 x_step
= (x_max
- x_min
) / LCD_WIDTH
;
582 x_delta
= (x_step
* LCD_WIDTH
) / 8;
583 y_step
= (y_max
- y_min
) / LCD_HEIGHT
;
584 y_delta
= (y_step
* LCD_HEIGHT
) / 8;
585 step_log2
= ilog2_fp(MIN(x_step
, y_step
));
586 max_iter
= MAX(15, -15 * step_log2
- 45);
589 #if CONFIG_LCD == LCD_SSD1815
590 /* Recorder, Ondio: pixel_height == 1.25 * pixel_width */
591 #define MB_HEIGHT (LCD_HEIGHT*5/4)
594 #define MB_HEIGHT LCD_HEIGHT
597 #define MB_XOFS (-0x03000000L) /* -0.75 (s5.26) */
598 #if 3000*MB_HEIGHT/LCD_WIDTH >= 2400 /* width is limiting factor */
599 #define MB_XFAC (0x06000000LL) /* 1.5 (s5.26) */
600 #define MB_YFAC (MB_XFAC*MB_HEIGHT/LCD_WIDTH)
601 #else /* height is limiting factor */
602 #define MB_YFAC (0x04cccccdLL) /* 1.2 (s5.26) */
603 #define MB_XFAC (MB_YFAC*LCD_WIDTH/MB_HEIGHT)
606 void init_mandelbrot_set(void)
608 x_min
= MB_XOFS
-MB_XFAC
;
609 x_max
= MB_XOFS
+MB_XFAC
;
615 void calc_mandelbrot_low_prec(void)
617 long start_tick
, last_yield
;
619 long next_update
= *rb
->current_tick
;
620 int last_px
= px_min
;
624 short x
, x2
, y
, y2
, a
, b
;
627 start_tick
= last_yield
= *rb
->current_tick
;
629 for (p_x
= 0, a32
= x_min
; p_x
< px_max
; p_x
++, a32
+= x_step
) {
633 for (p_y
= LCD_HEIGHT
-1, b32
= y_min
; p_y
>= py_min
; p_y
--, b32
+= y_step
) {
641 while (++n_iter
<= max_iter
) {
642 x2
= MULS16_ASR10(x
, x
);
643 y2
= MULS16_ASR10(y
, y
);
645 if (x2
+ y2
> (4<<10)) break;
647 y
= 2 * MULS16_ASR10(x
, y
) + b
;
651 if (n_iter
> max_iter
)
652 imgbuffer
[p_y
] = color
[8];
654 imgbuffer
[p_y
] = color
[n_iter
& 7];
656 /* be nice to other threads:
657 * if at least one tick has passed, yield */
658 if (TIME_AFTER(*rb
->current_tick
, last_yield
)) {
660 last_yield
= *rb
->current_tick
;
664 grey_ub_gray_bitmap_part(imgbuffer
, 0, py_min
, 1,
665 p_x
, py_min
, 1, py_max
- py_min
);
667 rb
->lcd_bitmap_part(imgbuffer
, 0, py_min
, 1,
668 p_x
, py_min
, 1, py_max
- py_min
);
669 if ((p_x
== px_max
- 1) || TIME_AFTER(*rb
->current_tick
, next_update
))
671 next_update
= *rb
->current_tick
+ UPDATE_FREQ
;
672 rb
->lcd_update_rect(last_px
, py_min
, p_x
- last_px
+ 1,
680 void calc_mandelbrot_high_prec(void)
682 long start_tick
, last_yield
;
684 long next_update
= *rb
->current_tick
;
685 int last_px
= px_min
;
688 long x
, x2
, y
, y2
, a
, b
;
692 start_tick
= last_yield
= *rb
->current_tick
;
694 for (p_x
= 0, a
= x_min
; p_x
< px_max
; p_x
++, a
+= x_step
) {
697 for (p_y
= LCD_HEIGHT
-1, b
= y_min
; p_y
>= py_min
; p_y
--, b
+= y_step
) {
704 while (++n_iter
<= max_iter
) {
705 x2
= MULS32_ASR26(x
, x
);
706 y2
= MULS32_ASR26(y
, y
);
708 if (x2
+ y2
> (4L<<26)) break;
710 y
= 2 * MULS32_ASR26(x
, y
) + b
;
714 if (n_iter
> max_iter
)
715 imgbuffer
[p_y
] = color
[8];
717 imgbuffer
[p_y
] = color
[n_iter
& 7];
719 /* be nice to other threads:
720 * if at least one tick has passed, yield */
721 if (TIME_AFTER(*rb
->current_tick
, last_yield
)) {
723 last_yield
= *rb
->current_tick
;
727 grey_ub_gray_bitmap_part(imgbuffer
, 0, py_min
, 1,
728 p_x
, py_min
, 1, py_max
- py_min
);
730 rb
->lcd_bitmap_part(imgbuffer
, 0, py_min
, 1,
731 p_x
, py_min
, 1, py_max
-py_min
);
732 if ((p_x
== px_max
- 1) || TIME_AFTER(*rb
->current_tick
, next_update
))
734 next_update
= *rb
->current_tick
+ UPDATE_FREQ
;
735 rb
->lcd_update_rect(last_px
, py_min
, p_x
- last_px
+ 1,
743 void cleanup(void *parameter
)
751 #define REDRAW_NONE 0
752 #define REDRAW_PARTIAL 1
753 #define REDRAW_FULL 2
755 enum plugin_status
plugin_start(const void* parameter
)
758 int lastbutton
= BUTTON_NONE
;
759 int redraw
= REDRAW_FULL
;
764 /* get the remainder of the plugin buffer */
765 gbuf
= (unsigned char *) rb
->plugin_get_buffer(&gbuf_size
);
767 /* initialize the greyscale buffer.*/
768 if (!grey_init(gbuf
, gbuf_size
, GREY_ON_COP
,
769 LCD_WIDTH
, LCD_HEIGHT
, NULL
))
771 rb
->splash(HZ
, "Couldn't init greyscale display");
774 grey_show(true); /* switch on greyscale overlay */
778 rb
->lcd_set_backdrop(NULL
);
781 init_mandelbrot_set();
785 if (redraw
> REDRAW_NONE
) {
786 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
789 if (redraw
== REDRAW_FULL
) {
790 MYLCD(clear_display
)();
794 if (step_log2
<= -10) /* select precision */
795 calc_mandelbrot_high_prec();
797 calc_mandelbrot_low_prec();
799 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
800 rb
->cpu_boost(false);
806 redraw
= REDRAW_NONE
;
809 button
= rb
->button_get(true);
811 #ifdef MANDELBROT_RC_QUIT
812 case MANDELBROT_RC_QUIT
:
814 case MANDELBROT_QUIT
:
820 case MANDELBROT_ZOOM_OUT
:
821 #ifdef MANDELBROT_ZOOM_OUT_PRE
822 if (lastbutton
!= MANDELBROT_ZOOM_OUT_PRE
)
830 redraw
= REDRAW_FULL
;
834 case MANDELBROT_ZOOM_IN
:
835 #ifdef MANDELBROT_ZOOM_IN_PRE
836 if (lastbutton
!= MANDELBROT_ZOOM_IN_PRE
)
839 #ifdef MANDELBROT_ZOOM_IN2
840 case MANDELBROT_ZOOM_IN2
:
847 redraw
= REDRAW_FULL
;
853 MYXLCD(scroll_down
)(LCD_HEIGHT
/8);
855 py_max
= (LCD_HEIGHT
/8);
856 redraw
= REDRAW_PARTIAL
;
859 case MANDELBROT_DOWN
:
862 MYXLCD(scroll_up
)(LCD_HEIGHT
/8);
864 py_min
= (LCD_HEIGHT
-LCD_HEIGHT
/8);
865 redraw
= REDRAW_PARTIAL
;
868 case MANDELBROT_LEFT
:
871 MYXLCD(scroll_right
)(LCD_WIDTH
/8);
873 px_max
= (LCD_WIDTH
/8);
874 redraw
= REDRAW_PARTIAL
;
877 case MANDELBROT_RIGHT
:
880 MYXLCD(scroll_left
)(LCD_WIDTH
/8);
882 px_min
= (LCD_WIDTH
-LCD_WIDTH
/8);
883 redraw
= REDRAW_PARTIAL
;
886 case MANDELBROT_MAXITER_DEC
:
887 #ifdef MANDELBROT_MAXITER_DEC_PRE
888 if (lastbutton
!= MANDELBROT_MAXITER_DEC_PRE
)
891 if (max_iter
>= 15) {
892 max_iter
-= max_iter
/ 3;
893 redraw
= REDRAW_FULL
;
897 case MANDELBROT_MAXITER_INC
:
898 #ifdef MANDELBROT_MAXITER_INC_PRE
899 if (lastbutton
!= MANDELBROT_MAXITER_INC_PRE
)
902 max_iter
+= max_iter
/ 2;
903 redraw
= REDRAW_FULL
;
906 case MANDELBROT_RESET
:
907 init_mandelbrot_set();
908 redraw
= REDRAW_FULL
;
912 if (rb
->default_event_handler_ex(button
, cleanup
, NULL
)
913 == SYS_USB_CONNECTED
)
914 return PLUGIN_USB_CONNECTED
;
917 if (button
!= BUTTON_NONE
)