summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/fire.c7
-rw-r--r--apps/plugins/grayscale.c8
-rw-r--r--apps/plugins/lib/gray_core.c294
-rw-r--r--apps/plugins/lib/gray_draw.c267
-rw-r--r--apps/plugins/mandelbrot.c13
5 files changed, 586 insertions, 3 deletions
diff --git a/apps/plugins/fire.c b/apps/plugins/fire.c
index 7b8a104ec0..fb08e5a5f1 100644
--- a/apps/plugins/fire.c
+++ b/apps/plugins/fire.c
@@ -111,6 +111,13 @@ static unsigned char draw_buffer[8*LCD_WIDTH];
111#define FIRE_INCREASE_MULT BUTTON_SCROLL_UP 111#define FIRE_INCREASE_MULT BUTTON_SCROLL_UP
112#define FIRE_DECREASE_MULT BUTTON_SCROLL_DOWN 112#define FIRE_DECREASE_MULT BUTTON_SCROLL_DOWN
113 113
114#elif (CONFIG_KEYPAD == IRIVER_IFP7XX_PAD)
115#define FIRE_QUIT BUTTON_PLAY
116#define FIRE_SWITCH_FLAMES_TYPE BUTTON_MODE
117#define FIRE_SWITCH_FLAMES_MOVING BUTTON_EQ
118#define FIRE_INCREASE_MULT BUTTON_UP
119#define FIRE_DECREASE_MULT BUTTON_DOWN
120
114#endif 121#endif
115 122
116#define MIN_FLAME_VALUE 0 123#define MIN_FLAME_VALUE 0
diff --git a/apps/plugins/grayscale.c b/apps/plugins/grayscale.c
index cc07ff37e5..56e1ce0e31 100644
--- a/apps/plugins/grayscale.c
+++ b/apps/plugins/grayscale.c
@@ -62,6 +62,14 @@ PLUGIN_HEADER
62#define GRAYSCALE_LEFT BUTTON_LEFT 62#define GRAYSCALE_LEFT BUTTON_LEFT
63#define GRAYSCALE_RIGHT BUTTON_RIGHT 63#define GRAYSCALE_RIGHT BUTTON_RIGHT
64#define GRAYSCALE_OFF BUTTON_MENU 64#define GRAYSCALE_OFF BUTTON_MENU
65
66#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
67#define GRAYSCALE_SHIFT BUTTON_PLAY
68#define GRAYSCALE_UP BUTTON_UP
69#define GRAYSCALE_DOWN BUTTON_DOWN
70#define GRAYSCALE_LEFT BUTTON_LEFT
71#define GRAYSCALE_RIGHT BUTTON_RIGHT
72#define GRAYSCALE_OFF BUTTON_EQ
65#endif 73#endif
66 74
67#define GFX_HEIGHT (LCD_HEIGHT-8) 75#define GFX_HEIGHT (LCD_HEIGHT-8)
diff --git a/apps/plugins/lib/gray_core.c b/apps/plugins/lib/gray_core.c
index e4cc5e869d..d8dddb3240 100644
--- a/apps/plugins/lib/gray_core.c
+++ b/apps/plugins/lib/gray_core.c
@@ -40,8 +40,9 @@ struct _gray_info _gray_info; /* global info structure */
40#ifndef SIMULATOR 40#ifndef SIMULATOR
41short _gray_random_buffer; /* buffer for random number generator */ 41short _gray_random_buffer; /* buffer for random number generator */
42 42
43#if CONFIG_LCD == LCD_SSD1815 43#if CONFIG_LCD == LCD_SSD1815 || CONFIG_LCD == LCD_IFP7XX
44/* measured and interpolated curve */ 44/* measured and interpolated curve */
45/* TODO: check for iFP */
45static const unsigned char lcdlinear[256] = { 46static const unsigned char lcdlinear[256] = {
46 0, 3, 5, 8, 11, 13, 16, 18, 47 0, 3, 5, 8, 11, 13, 16, 18,
47 21, 23, 26, 28, 31, 33, 36, 38, 48 21, 23, 26, 28, 31, 33, 36, 38,
@@ -112,7 +113,7 @@ static const unsigned char lcdlinear[256] = {
112 227, 228, 230, 232, 233, 235, 237, 239, 113 227, 228, 230, 232, 233, 235, 237, 239,
113 241, 243, 245, 247, 249, 251, 253, 255 114 241, 243, 245, 247, 249, 251, 253, 255
114}; 115};
115#elif (CONFIG_LCD == LCD_IPOD2BPP) || (CONFIG_LCD == LCD_IPODMINI) 116#elif (CONFIG_LCD == LCD_IPOD2BPP) || (CONFIG_LCD == LCD_IPODMINI) || (CONFIG_LCD == LCD_IFP7XX)
116/* measured and interpolated curve for mini LCD */ 117/* measured and interpolated curve for mini LCD */
117/* TODO: verify this curve on the fullsize greyscale LCD */ 118/* TODO: verify this curve on the fullsize greyscale LCD */
118static const unsigned char lcdlinear[256] = { 119static const unsigned char lcdlinear[256] = {
@@ -556,7 +557,7 @@ void gray_show(bool enable)
556#elif CONFIG_LCD == LCD_IPODMINI 557#elif CONFIG_LCD == LCD_IPODMINI
557 _gray_rb->timer_register(1, NULL, TIMER_FREQ / 88, 1, _timer_isr); 558 _gray_rb->timer_register(1, NULL, TIMER_FREQ / 88, 1, _timer_isr);
558#elif CONFIG_LCD == LCD_IFP7XX 559#elif CONFIG_LCD == LCD_IFP7XX
559 (void)_timer_isr; /* TODO: implement for iFP */ 560 _gray_rb->timer_register(1, NULL, TIMER_FREQ / 83, 1, _timer_isr);
560#endif /* CONFIG_LCD */ 561#endif /* CONFIG_LCD */
561#endif /* !SIMULATOR */ 562#endif /* !SIMULATOR */
562 _gray_rb->screen_dump_set_hook(gray_screendump_hook); 563 _gray_rb->screen_dump_set_hook(gray_screendump_hook);
@@ -1840,6 +1841,293 @@ void gray_update_rect(int x, int y, int width, int height)
1840 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a0" 1841 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a0"
1841 ); 1842 );
1842 } 1843 }
1844#elif defined(CPU_ARM)
1845 asm volatile
1846 (
1847 "ldr r0, [%[cbuf]] \n"
1848 "ldr r1, [%[bbuf]] \n"
1849 "eor r1, r0, r1 \n"
1850 "ldr r0, [%[cbuf], #4] \n"
1851 "ldr %[chg], [%[bbuf], #4] \n"
1852 "eor %[chg], r0, %[chg] \n"
1853 "orr %[chg], %[chg], r1 \n"
1854 : /* outputs */
1855 [chg] "=&r"(change)
1856 : /* inputs */
1857 [cbuf]"r"(cbuf),
1858 [bbuf]"r"(bbuf)
1859 : /* clobbers */
1860 "r0", "r1"
1861 );
1862
1863 if (change != 0)
1864 {
1865 unsigned char *addr;
1866 unsigned mask, depth, trash;
1867
1868 pat_ptr = &pat_stack[0];
1869
1870 /* precalculate the bit patterns with random shifts
1871 * for all 8 pixels and put them on an extra "stack" */
1872 asm volatile
1873 (
1874 "mov r3, #8 \n" /* loop count */
1875 "mov %[mask], #0 \n"
1876
1877 ".ur_pre_loop: \n"
1878 "ldrb r0, [%[cbuf]], #1 \n" /* read current buffer */
1879 "ldrb r1, [%[bbuf]] \n" /* read back buffer */
1880 "strb r0, [%[bbuf]], #1 \n" /* update back buffer */
1881 "mov r2, #0 \n" /* preset for skipped pixel */
1882 "cmp r0, r1 \n" /* no change? */
1883 "beq .ur_skip \n" /* -> skip */
1884
1885 "ldr r2, [%[bpat], r0, lsl #2] \n" /* r2 = bitpattern[byte]; */
1886
1887 "add %[rnd], %[rnd], %[rnd], lsl #2 \n" /* multiply by 75 */
1888 "rsb %[rnd], %[rnd], %[rnd], lsl #4 \n"
1889 "add %[rnd], %[rnd], #74 \n" /* add another 74 */
1890 /* Since the lower bits are not very random: get bits 8..15 (need max. 5) */
1891 "and r1, %[rmsk], %[rnd], lsr #8 \n" /* ..and mask out unneeded bits */
1892
1893 "cmp r1, %[dpth] \n" /* random >= depth ? */
1894 "subhs r1, r1, %[dpth] \n" /* yes: random -= depth */
1895
1896 "mov r0, r2, lsl r1 \n" /** rotate pattern **/
1897 "sub r1, %[dpth], r1 \n"
1898 "orr r2, r0, r2, lsr r1 \n"
1899
1900 "orr %[mask], %[mask], #0x100 \n" /* set mask bit */
1901
1902 ".ur_skip: \n"
1903 "mov %[mask], %[mask], lsr #1 \n" /* shift mask */
1904 "str r2, [%[patp]], #4 \n" /* push on pattern stack */
1905
1906 "subs r3, r3, #1 \n" /* loop 8 times (pixel block) */
1907 "bne .ur_pre_loop \n"
1908 : /* outputs */
1909 [cbuf]"+r"(cbuf),
1910 [bbuf]"+r"(bbuf),
1911 [patp]"+r"(pat_ptr),
1912 [rnd] "+r"(_gray_random_buffer),
1913 [mask]"=&r"(mask)
1914 : /* inputs */
1915 [bpat]"r"(_gray_info.bitpattern),
1916 [dpth]"r"(_gray_info.depth),
1917 [rmsk]"r"(_gray_info.randmask)
1918 : /* clobbers */
1919 "r0", "r1", "r2", "r3"
1920 );
1921
1922 addr = dst_row;
1923 depth = _gray_info.depth;
1924
1925 /* set the bits for all 8 pixels in all bytes according to the
1926 * precalculated patterns on the pattern stack */
1927 asm volatile
1928 (
1929 "ldmdb %[patp], {r1 - r8} \n" /* pop all 8 patterns */
1930
1931 /** Rotate the four 8x8 bit "blocks" within r1..r8 **/
1932
1933 "mov %[rx], #0xF0 \n" /** Stage 1: 4 bit "comb" **/
1934 "orr %[rx], %[rx], %[rx], lsl #8 \n"
1935 "orr %[rx], %[rx], %[rx], lsl #16\n" /* bitmask = ...11110000 */
1936 "eor r0, r1, r5, lsl #4 \n"
1937 "and r0, r0, %[rx] \n"
1938 "eor r1, r1, r0 \n" /* r1 = ...e3e2e1e0a3a2a1a0 */
1939 "eor r5, r5, r0, lsr #4 \n" /* r5 = ...e7e6e5e4a7a6a5a4 */
1940 "eor r0, r2, r6, lsl #4 \n"
1941 "and r0, r0, %[rx] \n"
1942 "eor r2, r2, r0 \n" /* r2 = ...f3f2f1f0b3b2b1b0 */
1943 "eor r6, r6, r0, lsr #4 \n" /* r6 = ...f7f6f5f4f7f6f5f4 */
1944 "eor r0, r3, r7, lsl #4 \n"
1945 "and r0, r0, %[rx] \n"
1946 "eor r3, r3, r0 \n" /* r3 = ...g3g2g1g0c3c2c1c0 */
1947 "eor r7, r7, r0, lsr #4 \n" /* r7 = ...g7g6g5g4c7c6c5c4 */
1948 "eor r0, r4, r8, lsl #4 \n"
1949 "and r0, r0, %[rx] \n"
1950 "eor r4, r4, r0 \n" /* r4 = ...h3h2h1h0d3d2d1d0 */
1951 "eor r8, r8, r0, lsr #4 \n" /* r8 = ...h7h6h5h4d7d6d5d4 */
1952
1953 "mov %[rx], #0xCC \n" /** Stage 2: 2 bit "comb" **/
1954 "orr %[rx], %[rx], %[rx], lsl #8 \n"
1955 "orr %[rx], %[rx], %[rx], lsl #16\n" /* bitmask = ...11001100 */
1956 "eor r0, r1, r3, lsl #2 \n"
1957 "and r0, r0, %[rx] \n"
1958 "eor r1, r1, r0 \n" /* r1 = ...g1g0e1e0c1c0a1a0 */
1959 "eor r3, r3, r0, lsr #2 \n" /* r3 = ...g3g2e3e2c3c2a3a2 */
1960 "eor r0, r2, r4, lsl #2 \n"
1961 "and r0, r0, %[rx] \n"
1962 "eor r2, r2, r0 \n" /* r2 = ...h1h0f1f0d1d0b1b0 */
1963 "eor r4, r4, r0, lsr #2 \n" /* r4 = ...h3h2f3f2d3d2b3b2 */
1964 "eor r0, r5, r7, lsl #2 \n"
1965 "and r0, r0, %[rx] \n"
1966 "eor r5, r5, r0 \n" /* r5 = ...g5g4e5e4c5c4a5a4 */
1967 "eor r7, r7, r0, lsr #2 \n" /* r7 = ...g7g6e7e6c7c6a7a6 */
1968 "eor r0, r6, r8, lsl #2 \n"
1969 "and r0, r0, %[rx] \n"
1970 "eor r6, r6, r0 \n" /* r6 = ...h5h4f5f4d5d4b5b4 */
1971 "eor r8, r8, r0, lsr #2 \n" /* r8 = ...h7h6f7f6d7d6b7b6 */
1972
1973 "mov %[rx], #0xAA \n" /** Stage 3: 1 bit "comb" **/
1974 "orr %[rx], %[rx], %[rx], lsl #8 \n"
1975 "orr %[rx], %[rx], %[rx], lsl #16\n" /* bitmask = ...10101010 */
1976 "eor r0, r1, r2, lsl #1 \n"
1977 "and r0, r0, %[rx] \n"
1978 "eor r1, r1, r0 \n" /* r1 = ...h0g0f0e0d0c0b0a0 */
1979 "eor r2, r2, r0, lsr #1 \n" /* r2 = ...h1g1f1e1d1c1b1a1 */
1980 "eor r0, r3, r4, lsl #1 \n"
1981 "and r0, r0, %[rx] \n"
1982 "eor r3, r3, r0 \n" /* r3 = ...h2g2f2e2d2c2b2a2 */
1983 "eor r4, r4, r0, lsr #1 \n" /* r4 = ...h3g3f3e3d3c3b3a3 */
1984 "eor r0, r5, r6, lsl #1 \n"
1985 "and r0, r0, %[rx] \n"
1986 "eor r5, r5, r0 \n" /* r5 = ...h4g4f4e4d4c4b4a4 */
1987 "eor r6, r6, r0, lsr #1 \n" /* r6 = ...h5g5f5e5d5c5b5a5 */
1988 "eor r0, r7, r8, lsl #1 \n"
1989 "and r0, r0, %[rx] \n"
1990 "eor r7, r7, r0 \n" /* r7 = ...h6g6f6e6d6c6b6a6 */
1991 "eor r8, r8, r0, lsr #1 \n" /* r8 = ...h7g7f7e7d7c7b7a7 */
1992
1993 "sub r0, %[dpth], #1 \n" /** shift out unused low bytes **/
1994 "and r0, r0, #7 \n"
1995 "add pc, pc, r0, lsl #2 \n" /* jump into shift streak */
1996 "mov r8, r8, lsr #8 \n" /* r8: never reached */
1997 "mov r7, r7, lsr #8 \n"
1998 "mov r6, r6, lsr #8 \n"
1999 "mov r5, r5, lsr #8 \n"
2000 "mov r4, r4, lsr #8 \n"
2001 "mov r3, r3, lsr #8 \n"
2002 "mov r2, r2, lsr #8 \n"
2003 "mov r1, r1, lsr #8 \n"
2004
2005 "mvn %[mask], %[mask] \n" /* "set" mask -> "keep" mask */
2006 "ands %[mask], %[mask], #0xff \n"
2007 "beq .ur_sstart \n" /* short loop if no bits to keep */
2008
2009 "ldrb r0, [pc, r0] \n" /* jump into full loop */
2010 "add pc, pc, r0 \n"
2011 ".ur_ftable: \n"
2012 ".byte .ur_f1 - .ur_ftable - 4 \n" /* [jump tables are tricky] */
2013 ".byte .ur_f2 - .ur_ftable - 4 \n"
2014 ".byte .ur_f3 - .ur_ftable - 4 \n"
2015 ".byte .ur_f4 - .ur_ftable - 4 \n"
2016 ".byte .ur_f5 - .ur_ftable - 4 \n"
2017 ".byte .ur_f6 - .ur_ftable - 4 \n"
2018 ".byte .ur_f7 - .ur_ftable - 4 \n"
2019 ".byte .ur_f8 - .ur_ftable - 4 \n"
2020
2021 ".ur_floop: \n" /** full loop (bits to keep)**/
2022 ".ur_f8: \n"
2023 "ldrb r0, [%[addr]] \n" /* load old byte */
2024 "and r0, r0, %[mask] \n" /* mask out replaced bits */
2025 "orr r0, r0, r1 \n" /* set new bits */
2026 "strb r0, [%[addr]], %[psiz] \n" /* store byte */
2027 "mov r1, r1, lsr #8 \n" /* shift out used-up byte */
2028 ".ur_f7: \n"
2029 "ldrb r0, [%[addr]] \n"
2030 "and r0, r0, %[mask] \n"
2031 "orr r0, r0, r2 \n"
2032 "strb r0, [%[addr]], %[psiz] \n"
2033 "mov r2, r2, lsr #8 \n"
2034 ".ur_f6: \n"
2035 "ldrb r0, [%[addr]] \n"
2036 "and r0, r0, %[mask] \n"
2037 "orr r0, r0, r3 \n"
2038 "strb r0, [%[addr]], %[psiz] \n"
2039 "mov r3, r3, lsr #8 \n"
2040 ".ur_f5: \n"
2041 "ldrb r0, [%[addr]] \n"
2042 "and r0, r0, %[mask] \n"
2043 "orr r0, r0, r4 \n"
2044 "strb r0, [%[addr]], %[psiz] \n"
2045 "mov r4, r4, lsr #8 \n"
2046 ".ur_f4: \n"
2047 "ldrb r0, [%[addr]] \n"
2048 "and r0, r0, %[mask] \n"
2049 "orr r0, r0, r5 \n"
2050 "strb r0, [%[addr]], %[psiz] \n"
2051 "mov r5, r5, lsr #8 \n"
2052 ".ur_f3: \n"
2053 "ldrb r0, [%[addr]] \n"
2054 "and r0, r0, %[mask] \n"
2055 "orr r0, r0, r6 \n"
2056 "strb r0, [%[addr]], %[psiz] \n"
2057 "mov r6, r6, lsr #8 \n"
2058 ".ur_f2: \n"
2059 "ldrb r0, [%[addr]] \n"
2060 "and r0, r0, %[mask] \n"
2061 "orr r0, r0, r7 \n"
2062 "strb r0, [%[addr]], %[psiz] \n"
2063 "mov r7, r7, lsr #8 \n"
2064 ".ur_f1: \n"
2065 "ldrb r0, [%[addr]] \n"
2066 "and r0, r0, %[mask] \n"
2067 "orr r0, r0, r8 \n"
2068 "strb r0, [%[addr]], %[psiz] \n"
2069 "mov r8, r8, lsr #8 \n"
2070
2071 "subs %[dpth], %[dpth], #8 \n" /* next round if anything left */
2072 "bhi .ur_floop \n"
2073
2074 "b .ur_end \n"
2075
2076 ".ur_sstart: \n"
2077 "ldrb r0, [pc, r0] \n" /* jump into short loop*/
2078 "add pc, pc, r0 \n"
2079 ".ur_stable: \n"
2080 ".byte .ur_s1 - .ur_stable - 4 \n"
2081 ".byte .ur_s2 - .ur_stable - 4 \n"
2082 ".byte .ur_s3 - .ur_stable - 4 \n"
2083 ".byte .ur_s4 - .ur_stable - 4 \n"
2084 ".byte .ur_s5 - .ur_stable - 4 \n"
2085 ".byte .ur_s6 - .ur_stable - 4 \n"
2086 ".byte .ur_s7 - .ur_stable - 4 \n"
2087 ".byte .ur_s8 - .ur_stable - 4 \n"
2088
2089 ".ur_sloop: \n" /** short loop (nothing to keep) **/
2090 ".ur_s8: \n"
2091 "strb r1, [%[addr]], %[psiz] \n" /* store byte */
2092 "mov r1, r1, lsr #8 \n" /* shift out used-up byte */
2093 ".ur_s7: \n"
2094 "strb r2, [%[addr]], %[psiz] \n"
2095 "mov r2, r2, lsr #8 \n"
2096 ".ur_s6: \n"
2097 "strb r3, [%[addr]], %[psiz] \n"
2098 "mov r3, r3, lsr #8 \n"
2099 ".ur_s5: \n"
2100 "strb r4, [%[addr]], %[psiz] \n"
2101 "mov r4, r4, lsr #8 \n"
2102 ".ur_s4: \n"
2103 "strb r5, [%[addr]], %[psiz] \n"
2104 "mov r5, r5, lsr #8 \n"
2105 ".ur_s3: \n"
2106 "strb r6, [%[addr]], %[psiz] \n"
2107 "mov r6, r6, lsr #8 \n"
2108 ".ur_s2: \n"
2109 "strb r7, [%[addr]], %[psiz] \n"
2110 "mov r7, r7, lsr #8 \n"
2111 ".ur_s1: \n"
2112 "strb r8, [%[addr]], %[psiz] \n"
2113 "mov r8, r8, lsr #8 \n"
2114
2115 "subs %[dpth], %[dpth], #8 \n" /* next round if anything left */
2116 "bhi .ur_sloop \n"
2117
2118 ".ur_end: \n"
2119 : /* outputs */
2120 [addr]"+r"(addr),
2121 [mask]"+r"(mask),
2122 [dpth]"+r"(depth),
2123 [rx] "=&r"(trash)
2124 : /* inputs */
2125 [psiz]"r"(_gray_info.plane_size),
2126 [patp]"[rx]"(pat_ptr)
2127 : /* clobbers */
2128 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8"
2129 );
2130 }
1843#else /* C version, for reference*/ 2131#else /* C version, for reference*/
1844#warning C version of gray_update_rect() used 2132#warning C version of gray_update_rect() used
1845 (void)pat_ptr; 2133 (void)pat_ptr;
diff --git a/apps/plugins/lib/gray_draw.c b/apps/plugins/lib/gray_draw.c
index b66b8d708a..4d75af5c9b 100644
--- a/apps/plugins/lib/gray_draw.c
+++ b/apps/plugins/lib/gray_draw.c
@@ -2006,6 +2006,273 @@ static void _writearray(unsigned char *address, const unsigned char *src,
2006 : /* clobbers */ 2006 : /* clobbers */
2007 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a0" 2007 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a0"
2008 ); 2008 );
2009#elif defined(CPU_ARM)
2010 const unsigned char *_src;
2011 unsigned _mask, depth, trash;
2012
2013 _mask = mask;
2014 _src = src;
2015
2016 pat_ptr = &pat_stack[0];
2017
2018 /* precalculate the bit patterns with random shifts
2019 for all 8 pixels and put them on an extra "stack" */
2020 asm volatile
2021 (
2022 "mov r3, #8 \n" /* loop count */
2023
2024 ".wa_loop: \n" /** load pattern for pixel **/
2025 "mov r2, #0 \n" /* pattern for skipped pixel must be 0 */
2026 "movs %[mask], %[mask], lsr #1 \n" /* shift out msb of mask */
2027 "bcc .wa_skip \n" /* skip this pixel */
2028
2029 "ldrb r0, [%[src]] \n" /* load src byte */
2030 "ldrb r0, [%[trns], r0] \n" /* idxtable into pattern index */
2031 "ldr r2, [%[bpat], r0, lsl #2] \n" /* r2 = bitpattern[byte]; */
2032
2033 "add %[rnd], %[rnd], %[rnd], lsl #2 \n" /* multiply by 75 */
2034 "rsb %[rnd], %[rnd], %[rnd], lsl #4 \n"
2035 "add %[rnd], %[rnd], #74 \n" /* add another 74 */
2036 /* Since the lower bits are not very random: get bits 8..15 (need max. 5) */
2037 "and r1, %[rmsk], %[rnd], lsr #8 \n" /* ..and mask out unneeded bits */
2038
2039 "cmp r1, %[dpth] \n" /* random >= depth ? */
2040 "subhs r1, r1, %[dpth] \n" /* yes: random -= depth */
2041
2042 "mov r0, r2, lsl r1 \n" /** rotate pattern **/
2043 "sub r1, %[dpth], r1 \n"
2044 "orr r2, r0, r2, lsr r1 \n"
2045
2046 ".wa_skip: \n"
2047 "str r2, [%[patp]], #4 \n" /* push on pattern stack */
2048
2049 "add %[src], %[src], %[stri] \n" /* src += stride; */
2050 "subs r3, r3, #1 \n" /* loop 8 times (pixel block) */
2051 "bne .wa_loop \n"
2052 : /* outputs */
2053 [src] "+r"(_src),
2054 [patp]"+r"(pat_ptr),
2055 [rnd] "+r"(_gray_random_buffer),
2056 [mask]"+r"(_mask)
2057 : /* inputs */
2058 [stri]"r"(stride),
2059 [bpat]"r"(_gray_info.bitpattern),
2060 [trns]"r"(_gray_info.idxtable),
2061 [dpth]"r"(_gray_info.depth),
2062 [rmsk]"r"(_gray_info.randmask)
2063 : /* clobbers */
2064 "r0", "r1", "r2", "r3"
2065 );
2066
2067 addr = address;
2068 _mask = mask;
2069 depth = _gray_info.depth;
2070
2071 /* set the bits for all 8 pixels in all bytes according to the
2072 * precalculated patterns on the pattern stack */
2073 asm volatile
2074 (
2075 "ldmdb %[patp], {r1 - r8} \n" /* pop all 8 patterns */
2076
2077 /** Rotate the four 8x8 bit "blocks" within r1..r8 **/
2078
2079 "mov %[rx], #0xF0 \n" /** Stage 1: 4 bit "comb" **/
2080 "orr %[rx], %[rx], %[rx], lsl #8 \n"
2081 "orr %[rx], %[rx], %[rx], lsl #16\n" /* bitmask = ...11110000 */
2082 "eor r0, r1, r5, lsl #4 \n"
2083 "and r0, r0, %[rx] \n"
2084 "eor r1, r1, r0 \n" /* r1 = ...e3e2e1e0a3a2a1a0 */
2085 "eor r5, r5, r0, lsr #4 \n" /* r5 = ...e7e6e5e4a7a6a5a4 */
2086 "eor r0, r2, r6, lsl #4 \n"
2087 "and r0, r0, %[rx] \n"
2088 "eor r2, r2, r0 \n" /* r2 = ...f3f2f1f0b3b2b1b0 */
2089 "eor r6, r6, r0, lsr #4 \n" /* r6 = ...f7f6f5f4f7f6f5f4 */
2090 "eor r0, r3, r7, lsl #4 \n"
2091 "and r0, r0, %[rx] \n"
2092 "eor r3, r3, r0 \n" /* r3 = ...g3g2g1g0c3c2c1c0 */
2093 "eor r7, r7, r0, lsr #4 \n" /* r7 = ...g7g6g5g4c7c6c5c4 */
2094 "eor r0, r4, r8, lsl #4 \n"
2095 "and r0, r0, %[rx] \n"
2096 "eor r4, r4, r0 \n" /* r4 = ...h3h2h1h0d3d2d1d0 */
2097 "eor r8, r8, r0, lsr #4 \n" /* r8 = ...h7h6h5h4d7d6d5d4 */
2098
2099 "mov %[rx], #0xCC \n" /** Stage 2: 2 bit "comb" **/
2100 "orr %[rx], %[rx], %[rx], lsl #8 \n"
2101 "orr %[rx], %[rx], %[rx], lsl #16\n" /* bitmask = ...11001100 */
2102 "eor r0, r1, r3, lsl #2 \n"
2103 "and r0, r0, %[rx] \n"
2104 "eor r1, r1, r0 \n" /* r1 = ...g1g0e1e0c1c0a1a0 */
2105 "eor r3, r3, r0, lsr #2 \n" /* r3 = ...g3g2e3e2c3c2a3a2 */
2106 "eor r0, r2, r4, lsl #2 \n"
2107 "and r0, r0, %[rx] \n"
2108 "eor r2, r2, r0 \n" /* r2 = ...h1h0f1f0d1d0b1b0 */
2109 "eor r4, r4, r0, lsr #2 \n" /* r4 = ...h3h2f3f2d3d2b3b2 */
2110 "eor r0, r5, r7, lsl #2 \n"
2111 "and r0, r0, %[rx] \n"
2112 "eor r5, r5, r0 \n" /* r5 = ...g5g4e5e4c5c4a5a4 */
2113 "eor r7, r7, r0, lsr #2 \n" /* r7 = ...g7g6e7e6c7c6a7a6 */
2114 "eor r0, r6, r8, lsl #2 \n"
2115 "and r0, r0, %[rx] \n"
2116 "eor r6, r6, r0 \n" /* r6 = ...h5h4f5f4d5d4b5b4 */
2117 "eor r8, r8, r0, lsr #2 \n" /* r8 = ...h7h6f7f6d7d6b7b6 */
2118
2119 "mov %[rx], #0xAA \n" /** Stage 3: 1 bit "comb" **/
2120 "orr %[rx], %[rx], %[rx], lsl #8 \n"
2121 "orr %[rx], %[rx], %[rx], lsl #16\n" /* bitmask = ...10101010 */
2122 "eor r0, r1, r2, lsl #1 \n"
2123 "and r0, r0, %[rx] \n"
2124 "eor r1, r1, r0 \n" /* r1 = ...h0g0f0e0d0c0b0a0 */
2125 "eor r2, r2, r0, lsr #1 \n" /* r2 = ...h1g1f1e1d1c1b1a1 */
2126 "eor r0, r3, r4, lsl #1 \n"
2127 "and r0, r0, %[rx] \n"
2128 "eor r3, r3, r0 \n" /* r3 = ...h2g2f2e2d2c2b2a2 */
2129 "eor r4, r4, r0, lsr #1 \n" /* r4 = ...h3g3f3e3d3c3b3a3 */
2130 "eor r0, r5, r6, lsl #1 \n"
2131 "and r0, r0, %[rx] \n"
2132 "eor r5, r5, r0 \n" /* r5 = ...h4g4f4e4d4c4b4a4 */
2133 "eor r6, r6, r0, lsr #1 \n" /* r6 = ...h5g5f5e5d5c5b5a5 */
2134 "eor r0, r7, r8, lsl #1 \n"
2135 "and r0, r0, %[rx] \n"
2136 "eor r7, r7, r0 \n" /* r7 = ...h6g6f6e6d6c6b6a6 */
2137 "eor r8, r8, r0, lsr #1 \n" /* r8 = ...h7g7f7e7d7c7b7a7 */
2138
2139 "sub r0, %[dpth], #1 \n" /** shift out unused low bytes **/
2140 "and r0, r0, #7 \n"
2141 "add pc, pc, r0, lsl #2 \n" /* jump into shift streak */
2142 "mov r8, r8, lsr #8 \n" /* r8: never reached */
2143 "mov r7, r7, lsr #8 \n"
2144 "mov r6, r6, lsr #8 \n"
2145 "mov r5, r5, lsr #8 \n"
2146 "mov r4, r4, lsr #8 \n"
2147 "mov r3, r3, lsr #8 \n"
2148 "mov r2, r2, lsr #8 \n"
2149 "mov r1, r1, lsr #8 \n"
2150
2151 "mvn %[mask], %[mask] \n" /* "set" mask -> "keep" mask */
2152 "ands %[mask], %[mask], #0xff \n"
2153 "beq .wa_sstart \n" /* short loop if no bits to keep */
2154
2155 "ldrb r0, [pc, r0] \n" /* jump into full loop */
2156 "add pc, pc, r0 \n"
2157 ".wa_ftable: \n"
2158 ".byte .wa_f1 - .wa_ftable - 4 \n" /* [jump tables are tricky] */
2159 ".byte .wa_f2 - .wa_ftable - 4 \n"
2160 ".byte .wa_f3 - .wa_ftable - 4 \n"
2161 ".byte .wa_f4 - .wa_ftable - 4 \n"
2162 ".byte .wa_f5 - .wa_ftable - 4 \n"
2163 ".byte .wa_f6 - .wa_ftable - 4 \n"
2164 ".byte .wa_f7 - .wa_ftable - 4 \n"
2165 ".byte .wa_f8 - .wa_ftable - 4 \n"
2166
2167 ".wa_floop: \n" /** full loop (bits to keep)**/
2168 ".wa_f8: \n"
2169 "ldrb r0, [%[addr]] \n" /* load old byte */
2170 "and r0, r0, %[mask] \n" /* mask out replaced bits */
2171 "orr r0, r0, r1 \n" /* set new bits */
2172 "strb r0, [%[addr]], %[psiz] \n" /* store byte */
2173 "mov r1, r1, lsr #8 \n" /* shift out used-up byte */
2174 ".wa_f7: \n"
2175 "ldrb r0, [%[addr]] \n"
2176 "and r0, r0, %[mask] \n"
2177 "orr r0, r0, r2 \n"
2178 "strb r0, [%[addr]], %[psiz] \n"
2179 "mov r2, r2, lsr #8 \n"
2180 ".wa_f6: \n"
2181 "ldrb r0, [%[addr]] \n"
2182 "and r0, r0, %[mask] \n"
2183 "orr r0, r0, r3 \n"
2184 "strb r0, [%[addr]], %[psiz] \n"
2185 "mov r3, r3, lsr #8 \n"
2186 ".wa_f5: \n"
2187 "ldrb r0, [%[addr]] \n"
2188 "and r0, r0, %[mask] \n"
2189 "orr r0, r0, r4 \n"
2190 "strb r0, [%[addr]], %[psiz] \n"
2191 "mov r4, r4, lsr #8 \n"
2192 ".wa_f4: \n"
2193 "ldrb r0, [%[addr]] \n"
2194 "and r0, r0, %[mask] \n"
2195 "orr r0, r0, r5 \n"
2196 "strb r0, [%[addr]], %[psiz] \n"
2197 "mov r5, r5, lsr #8 \n"
2198 ".wa_f3: \n"
2199 "ldrb r0, [%[addr]] \n"
2200 "and r0, r0, %[mask] \n"
2201 "orr r0, r0, r6 \n"
2202 "strb r0, [%[addr]], %[psiz] \n"
2203 "mov r6, r6, lsr #8 \n"
2204 ".wa_f2: \n"
2205 "ldrb r0, [%[addr]] \n"
2206 "and r0, r0, %[mask] \n"
2207 "orr r0, r0, r7 \n"
2208 "strb r0, [%[addr]], %[psiz] \n"
2209 "mov r7, r7, lsr #8 \n"
2210 ".wa_f1: \n"
2211 "ldrb r0, [%[addr]] \n"
2212 "and r0, r0, %[mask] \n"
2213 "orr r0, r0, r8 \n"
2214 "strb r0, [%[addr]], %[psiz] \n"
2215 "mov r8, r8, lsr #8 \n"
2216
2217 "subs %[dpth], %[dpth], #8 \n" /* next round if anything left */
2218 "bhi .wa_floop \n"
2219
2220 "b .wa_end \n"
2221
2222 ".wa_sstart: \n"
2223 "ldrb r0, [pc, r0] \n" /* jump into short loop*/
2224 "add pc, pc, r0 \n"
2225 ".wa_stable: \n"
2226 ".byte .wa_s1 - .wa_stable - 4 \n"
2227 ".byte .wa_s2 - .wa_stable - 4 \n"
2228 ".byte .wa_s3 - .wa_stable - 4 \n"
2229 ".byte .wa_s4 - .wa_stable - 4 \n"
2230 ".byte .wa_s5 - .wa_stable - 4 \n"
2231 ".byte .wa_s6 - .wa_stable - 4 \n"
2232 ".byte .wa_s7 - .wa_stable - 4 \n"
2233 ".byte .wa_s8 - .wa_stable - 4 \n"
2234
2235 ".wa_sloop: \n" /** short loop (nothing to keep) **/
2236 ".wa_s8: \n"
2237 "strb r1, [%[addr]], %[psiz] \n" /* store byte */
2238 "mov r1, r1, lsr #8 \n" /* shift out used-up byte */
2239 ".wa_s7: \n"
2240 "strb r2, [%[addr]], %[psiz] \n"
2241 "mov r2, r2, lsr #8 \n"
2242 ".wa_s6: \n"
2243 "strb r3, [%[addr]], %[psiz] \n"
2244 "mov r3, r3, lsr #8 \n"
2245 ".wa_s5: \n"
2246 "strb r4, [%[addr]], %[psiz] \n"
2247 "mov r4, r4, lsr #8 \n"
2248 ".wa_s4: \n"
2249 "strb r5, [%[addr]], %[psiz] \n"
2250 "mov r5, r5, lsr #8 \n"
2251 ".wa_s3: \n"
2252 "strb r6, [%[addr]], %[psiz] \n"
2253 "mov r6, r6, lsr #8 \n"
2254 ".wa_s2: \n"
2255 "strb r7, [%[addr]], %[psiz] \n"
2256 "mov r7, r7, lsr #8 \n"
2257 ".wa_s1: \n"
2258 "strb r8, [%[addr]], %[psiz] \n"
2259 "mov r8, r8, lsr #8 \n"
2260
2261 "subs %[dpth], %[dpth], #8 \n" /* next round if anything left */
2262 "bhi .wa_sloop \n"
2263
2264 ".wa_end: \n"
2265 : /* outputs */
2266 [addr]"+r"(addr),
2267 [mask]"+r"(_mask),
2268 [dpth]"+r"(depth),
2269 [rx] "=&r"(trash)
2270 : /* inputs */
2271 [psiz]"r"(_gray_info.plane_size),
2272 [patp]"[rx]"(pat_ptr)
2273 : /* clobbers */
2274 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8"
2275 );
2009#else /* C version, for reference*/ 2276#else /* C version, for reference*/
2010#warning C version of _writearray() used 2277#warning C version of _writearray() used
2011 unsigned char *end; 2278 unsigned char *end;
diff --git a/apps/plugins/mandelbrot.c b/apps/plugins/mandelbrot.c
index b1f243b01c..3ead7e0509 100644
--- a/apps/plugins/mandelbrot.c
+++ b/apps/plugins/mandelbrot.c
@@ -157,6 +157,19 @@ PLUGIN_HEADER
157#define MANDELBROT_MAXITER_DEC BUTTON_REW 157#define MANDELBROT_MAXITER_DEC BUTTON_REW
158#define MANDELBROT_RESET (BUTTON_PLAY | BUTTON_REW) 158#define MANDELBROT_RESET (BUTTON_PLAY | BUTTON_REW)
159 159
160#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
161#define MANDELBROT_QUIT BUTTON_EQ
162#define MANDELBROT_UP BUTTON_UP
163#define MANDELBROT_DOWN BUTTON_DOWN
164#define MANDELBROT_LEFT BUTTON_LEFT
165#define MANDELBROT_RIGHT BUTTON_RIGHT
166#define MANDELBROT_ZOOM_IN_PRE BUTTON_SELECT
167#define MANDELBROT_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
168#define MANDELBROT_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
169#define MANDELBROT_MAXITER_INC (BUTTON_PLAY | BUTTON_RIGHT)
170#define MANDELBROT_MAXITER_DEC (BUTTON_PLAY | BUTTON_LEFT)
171#define MANDELBROT_RESET BUTTON_MODE
172
160#endif 173#endif
161 174
162#if LCD_DEPTH < 8 175#if LCD_DEPTH < 8