summaryrefslogtreecommitdiff
path: root/apps/plugins/lib/gray_core.c
diff options
context:
space:
mode:
authorTomasz Malesinski <tomal@rockbox.org>2007-09-22 23:37:58 +0000
committerTomasz Malesinski <tomal@rockbox.org>2007-09-22 23:37:58 +0000
commit4fc77ac3ff8a4105b8e92a7f3d88b65b3bcea1cd (patch)
tree26583d60ee44505ac5a031dbd9beb36b5d19b467 /apps/plugins/lib/gray_core.c
parented83edfd7bb918927213ebff79bea87c0ffb0408 (diff)
downloadrockbox-4fc77ac3ff8a4105b8e92a7f3d88b65b3bcea1cd.tar.gz
rockbox-4fc77ac3ff8a4105b8e92a7f3d88b65b3bcea1cd.zip
Fix empty commit: Add grayscale support for ARM in vertical packing format.
Enable grayscale for Iriver ifp. Fix timer_unregister for PNX0101. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14825 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/lib/gray_core.c')
-rw-r--r--apps/plugins/lib/gray_core.c294
1 files changed, 291 insertions, 3 deletions
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;