summaryrefslogtreecommitdiff
path: root/apps/plugins/lib/gray_pixelfuncs.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lib/gray_pixelfuncs.c')
-rw-r--r--apps/plugins/lib/gray_pixelfuncs.c245
1 files changed, 0 insertions, 245 deletions
diff --git a/apps/plugins/lib/gray_pixelfuncs.c b/apps/plugins/lib/gray_pixelfuncs.c
deleted file mode 100644
index 31ce8deb3c..0000000000
--- a/apps/plugins/lib/gray_pixelfuncs.c
+++ /dev/null
@@ -1,245 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* Low level pixel drawing functions
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */
30#include "gray.h"
31
32/* Prototypes */
33static void _writepixel(int x, int y, unsigned long pattern);
34static void _invertpixel(int x, int y, unsigned long pattern);
35
36/* function pointer array */
37void (* const _gray_pixelfuncs[4])(int x, int y, unsigned long pattern) = {
38 _invertpixel, _writepixel, _writepixel, _writepixel
39};
40
41/* Set a pixel to a specific bit pattern (low level routine) */
42static void _writepixel(int x, int y, unsigned long pattern)
43{
44 register unsigned mask, random;
45 register unsigned char *address;
46
47 /* Some (pseudo-)random function must be used here to shift the bit
48 * pattern randomly, otherwise you would get flicker and/or moire.
49 * Since rand() is relatively slow, I've implemented a simple, but very
50 * fast pseudo-random generator based on linear congruency in assembler.
51 * It delivers max. 16 pseudo-random bits in each iteration. */
52
53 /* simple but fast pseudo-random generator */
54 asm (
55 "mov #75,r1 \n"
56 "mulu %1,r1 \n" /* multiply by 75 */
57 "sts macl,%1 \n" /* get result */
58 "add #74,%1 \n" /* add another 74 */
59 /* Since the lower bits are not very random: */
60 "swap.b %1,%0 \n" /* get bits 8..15 (need max. 5) */
61 "and %2,%0 \n" /* mask out unneeded bits */
62 : /* outputs */
63 /* %0 */ "=&r"(random),
64 /* %1, in & out */ "+r"(_gray_random_buffer)
65 : /* inputs */
66 /* %2 */ "r"(_graybuf->randmask)
67 : /* clobbers */
68 "r1", "macl"
69 );
70
71 /* precalculate mask and byte address in first bitplane */
72 asm (
73 "mov %3,%0 \n" /* take y as base for address offset */
74 "shlr2 %0 \n" /* shift right by 3 (= divide by 8) */
75 "shlr %0 \n"
76 "mulu %0,%2 \n" /* multiply with width */
77 "and #7,%3 \n" /* get lower 3 bits of y */
78 "sts macl,%0 \n" /* get mulu result */
79 "add %4,%0 \n" /* add base + x to get final address */
80
81 "mov %3,%1 \n" /* move lower 3 bits of y out of r0 */
82 "mova .wp_masktable,%3\n" /* get address of mask table in r0 */
83 "bra .wp_predone \n" /* skip the table */
84 "mov.b @(%3,%1),%1 \n" /* get entry from mask table */
85
86 ".align 2 \n"
87 ".wp_masktable: \n" /* mask table */
88 ".byte 0x01 \n"
89 ".byte 0x02 \n"
90 ".byte 0x04 \n"
91 ".byte 0x08 \n"
92 ".byte 0x10 \n"
93 ".byte 0x20 \n"
94 ".byte 0x40 \n"
95 ".byte 0x80 \n"
96
97 ".wp_predone: \n"
98 : /* outputs */
99 /* %0 */ "=&r"(address),
100 /* %1 */ "=&r"(mask)
101 : /* inputs */
102 /* %2 */ "r"(_graybuf->width),
103 /* %3 = r0 */ "z"(y),
104 /* %4 */ "r"(_graybuf->data + x)
105 : /* clobbers */
106 "macl"
107 );
108
109 /* the hard part: set bits in all bitplanes according to pattern */
110 asm volatile (
111 "cmp/hs %1,%5 \n" /* random >= depth ? */
112 "bf .wp_ntrim \n"
113 "sub %1,%5 \n" /* yes: random -= depth */
114 /* it's sufficient to do this once, since the mask guarantees
115 * random < 2 * depth */
116 ".wp_ntrim: \n"
117
118 /* calculate some addresses */
119 "mulu %4,%1 \n" /* end address offset */
120 "not %3,r1 \n" /* get inverse mask (for "and") */
121 "sts macl,%1 \n" /* result of mulu */
122 "mulu %4,%5 \n" /* address offset of <random>'th plane */
123 "add %2,%1 \n" /* end offset -> end address */
124 "sts macl,%5 \n" /* result of mulu */
125 "add %2,%5 \n" /* address of <random>'th plane */
126 "bra .wp_start1 \n"
127 "mov %5,r2 \n" /* copy address */
128
129 /* first loop: set bits from <random>'th bitplane to last */
130 ".wp_loop1: \n"
131 "mov.b @r2,r3 \n" /* get data byte */
132 "shlr %0 \n" /* shift bit mask, sets t bit */
133 "and r1,r3 \n" /* reset bit (-> "white") */
134 "bf .wp_white1 \n" /* t=0? -> "white" bit */
135 "or %3,r3 \n" /* set bit ("black" bit) */
136 ".wp_white1: \n"
137 "mov.b r3,@r2 \n" /* store data byte */
138 "add %4,r2 \n" /* advance address to next bitplane */
139 ".wp_start1: \n"
140 "cmp/hi r2,%1 \n" /* address < end address ? */
141 "bt .wp_loop1 \n"
142
143 "bra .wp_start2 \n"
144 "nop \n"
145
146 /* second loop: set bits from first to <random-1>'th bitplane
147 * Bit setting works the other way round here to equalize average
148 * execution times for bright and dark pixels */
149 ".wp_loop2: \n"
150 "mov.b @%2,r3 \n" /* get data byte */
151 "shlr %0 \n" /* shift bit mask, sets t bit */
152 "or %3,r3 \n" /* set bit (-> "black") */
153 "bt .wp_black2 \n" /* t=1? -> "black" bit */
154 "and r1,r3 \n" /* reset bit ("white" bit) */
155 ".wp_black2: \n"
156 "mov.b r3,@%2 \n" /* store data byte */
157 "add %4,%2 \n" /* advance address to next bitplane */
158 ".wp_start2: \n"
159 "cmp/hi %2,%5 \n" /* address < <random>'th address ? */
160 "bt .wp_loop2 \n"
161 : /* outputs */
162 : /* inputs */
163 /* %0 */ "r"(pattern),
164 /* %1 */ "r"(_graybuf->depth),
165 /* %2 */ "r"(address),
166 /* %3 */ "r"(mask),
167 /* %4 */ "r"(_graybuf->plane_size),
168 /* %5 */ "r"(random)
169 : /* clobbers */
170 "r1", "r2", "r3", "macl"
171 );
172}
173
174/* invert all bits for one pixel (low level routine) */
175static void _invertpixel(int x, int y, unsigned long pattern)
176{
177 register unsigned mask;
178 register unsigned char *address;
179
180 (void) pattern; /* not used for invert */
181
182 /* precalculate mask and byte address in first bitplane */
183 asm (
184 "mov %3,%0 \n" /* take y as base for address offset */
185 "shlr2 %0 \n" /* shift right by 3 (= divide by 8) */
186 "shlr %0 \n"
187 "mulu %0,%2 \n" /* multiply with width */
188 "and #7,%3 \n" /* get lower 3 bits of y */
189 "sts macl,%0 \n" /* get mulu result */
190 "add %4,%0 \n" /* add base + x to get final address */
191
192 "mov %3,%1 \n" /* move lower 3 bits of y out of r0 */
193 "mova .ip_masktable,%3\n" /* get address of mask table in r0 */
194 "bra .ip_predone \n" /* skip the table */
195 "mov.b @(%3,%1),%1 \n" /* get entry from mask table */
196
197 ".align 2 \n"
198 ".ip_masktable: \n" /* mask table */
199 ".byte 0x01 \n"
200 ".byte 0x02 \n"
201 ".byte 0x04 \n"
202 ".byte 0x08 \n"
203 ".byte 0x10 \n"
204 ".byte 0x20 \n"
205 ".byte 0x40 \n"
206 ".byte 0x80 \n"
207
208 ".ip_predone: \n"
209 : /* outputs */
210 /* %0 */ "=&r"(address),
211 /* %1 */ "=&r"(mask)
212 : /* inputs */
213 /* %2 */ "r"(_graybuf->width),
214 /* %3 = r0 */ "z"(y),
215 /* %4 */ "r"(_graybuf->data + x)
216 : /* clobbers */
217 "macl"
218 );
219
220 /* invert bits in all bitplanes */
221 asm volatile (
222 "mov #0,r1 \n" /* current_plane = 0 */
223
224 ".ip_loop: \n"
225 "mov.b @%1,r2 \n" /* get data byte */
226 "add #1,r1 \n" /* current_plane++; */
227 "xor %2,r2 \n" /* invert bits */
228 "mov.b r2,@%1 \n" /* store data byte */
229 "add %3,%1 \n" /* advance address to next bitplane */
230 "cmp/hi r1,%0 \n" /* current_plane < depth ? */
231 "bt .ip_loop \n"
232 : /* outputs */
233 : /* inputs */
234 /* %0 */ "r"(_graybuf->depth),
235 /* %1 */ "r"(address),
236 /* %2 */ "r"(mask),
237 /* %3 */ "r"(_graybuf->plane_size)
238 : /* clobbers */
239 "r1", "r2"
240 );
241}
242
243#endif // #ifdef HAVE_LCD_BITMAP
244#endif // #ifndef SIMULATOR
245