diff options
Diffstat (limited to 'firmware/target/coldfire/iaudio/x5/lcd-as-x5.S')
-rw-r--r-- | firmware/target/coldfire/iaudio/x5/lcd-as-x5.S | 334 |
1 files changed, 333 insertions, 1 deletions
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S index 323710cc57..1a527bb8f3 100644 --- a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S +++ b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S | |||
@@ -23,10 +23,342 @@ | |||
23 | 23 | ||
24 | .section .icode,"ax",@progbits | 24 | .section .icode,"ax",@progbits |
25 | 25 | ||
26 | /* begin lcd_write_yuv420_lines | ||
27 | * | ||
28 | * See http://en.wikipedia.org/wiki/YCbCr | ||
29 | * ITU-R BT.601 (formerly CCIR 601): | ||
30 | * |Y'| | 0.299000 0.587000 0.114000| |R| | ||
31 | * |Pb| = |-0.168736 -0.331264 0.500000| |G| or 0.564334*(B - Y') | ||
32 | * |Pr| | 0.500000 -0.418688 0.081312| |B| or 0.713267*(R - Y') | ||
33 | * Scaled, normalized and rounded: | ||
34 | * |Y'| | 65 129 25| |R| + 16 : 16->235 | ||
35 | * |Cb| = |-38 -74 112| |G| + 128 : 16->240 | ||
36 | * |Cr| |112 -94 -18| |B| + 128 : 16->240 | ||
37 | * | ||
38 | * The inverse: | ||
39 | * |R| |1.000000 -0.000001 1.402000| |Y'| | ||
40 | * |G| = |1.000000 -0.334136 -0.714136| |Pb| | ||
41 | * |B| |1.000000 1.772000 0.000000| |Pr| | ||
42 | * Scaled, normalized, rounded and tweaked to yield RGB 666: | ||
43 | * |R| |74 0 102| |Y' - 16| / 256 | ||
44 | * |G| = |74 -25 -52| |Cb - 128| / 256 | ||
45 | * |B| |74 129 0| |Cr - 128| / 256 | ||
46 | */ | ||
47 | .align 2 | ||
48 | .global lcd_write_yuv420_lines | ||
49 | .type lcd_write_yuv420_lines,@function | ||
50 | lcd_write_yuv420_lines: | ||
51 | lea.l (-40,%sp),%sp /* free up some registers */ | ||
52 | movem.l %d2-%d7/%a2-%a5,(%sp) | ||
53 | |||
54 | lea.l 0xf0008002,%a0 /* LCD data port */ | ||
55 | move.l (40+4,%sp),%a1 /* Y data */ | ||
56 | move.l (40+8,%sp),%a2 /* Cb data */ | ||
57 | move.l (40+12,%sp),%a3 /* guv storage */ | ||
58 | move.l (40+16,%sp),%a4 /* Cr data */ | ||
59 | move.l (40+20,%sp),%d0 /* width */ | ||
60 | lea.l (%a1,%d0.l),%a5 /* end address */ | ||
61 | |||
62 | .yuv_line_loop1: | ||
63 | /** Write first pixel **/ | ||
64 | clr.l %d1 /* get y component */ | ||
65 | move.b (%a1)+,%d1 | ||
66 | subq.l #8,%d1 | ||
67 | subq.l #8,%d1 | ||
68 | moveq.l #74,%d6 | ||
69 | muls.w %d6,%d1 | ||
70 | asr.l #8,%d1 | ||
71 | |||
72 | clr %d2 /* get bu component */ | ||
73 | move.b (%a2),%d2 | ||
74 | moveq.l #-128,%d6 | ||
75 | add.l %d6,%d2 | ||
76 | move.l %d2,%d3 /* %d3 = cb component for guv */ | ||
77 | move.w #129,%d6 | ||
78 | muls.w %d6,%d2 | ||
79 | asr.l #8,%d2 | ||
80 | move.b %d2,(%a2)+ /* save bu for next line */ | ||
81 | |||
82 | moveq.l #-25,%d6 /* multiply first term of guv */ | ||
83 | muls.w %d6,%d3 | ||
84 | |||
85 | clr %d4 /* get rv component */ | ||
86 | move.b (%a4),%d4 | ||
87 | moveq.l #-128,%d6 | ||
88 | add.l %d6,%d4 | ||
89 | move.l %d4,%d7 /* %d7 = cr component for guv */ | ||
90 | moveq.l #102,%d6 | ||
91 | muls.w %d6,%d4 | ||
92 | asr.l #8,%d4 | ||
93 | move.b %d4,(%a4)+ /* save rv for next line */ | ||
94 | |||
95 | moveq.l #-52,%d6 /* multiply second term of guv */ | ||
96 | muls.w %d6,%d7 | ||
97 | add.l %d7,%d3 | ||
98 | asr.l #8,%d3 | ||
99 | move.b %d3,(%a3)+ /* save guv for next line */ | ||
100 | /* : %d1 = Y, %d2 = bu, %d3 = guv, %d4 = rv */ | ||
101 | |||
102 | move.l %d1,%d5 /* get r */ | ||
103 | add.l %d4,%d5 | ||
104 | move.l %d1,%d6 /* get g */ | ||
105 | add.l %d3,%d6 | ||
106 | move.l %d1,%d7 /* get b */ | ||
107 | add.l %d2,%d7 | ||
108 | |||
109 | move.l %d7,%d1 /* is clamping needed? */ | ||
110 | or.l %d6,%d1 | ||
111 | or.l %d5,%d1 | ||
112 | asr.l #6,%d1 | ||
113 | beq.b .yuv_no_clamp1 /* values in range: skip clamping */ | ||
114 | bpl.b .yuv_r63_test1 /* no negative values: skip to high bounds checks */ | ||
115 | .yuv_r0_test1: | ||
116 | clr.l %d1 /* check for any values < 0 */ | ||
117 | cmp.l %d1,%d5 | ||
118 | bgt.b .yuv_g0_test1 | ||
119 | clr.l %d5 | ||
120 | .yuv_g0_test1: | ||
121 | cmp.l %d1,%d6 | ||
122 | bgt.b .yuv_b0_test1 | ||
123 | clr.l %d6 | ||
124 | .yuv_b0_test1: | ||
125 | cmp.l %d1,%d7 | ||
126 | bgt.b .yuv_r63_test1 | ||
127 | clr.l %d7 | ||
128 | .yuv_r63_test1: /* check for any values > 63 */ | ||
129 | moveq.l #63,%d1 | ||
130 | cmp.l %d1,%d5 | ||
131 | blt.b .yuv_g63_test1 | ||
132 | move.l %d1,%d5 | ||
133 | .yuv_g63_test1: | ||
134 | cmp.l %d1,%d6 | ||
135 | blt.b .yuv_b63_test1 | ||
136 | move.l %d1,%d6 | ||
137 | .yuv_b63_test1: | ||
138 | cmp.l %d1,%d7 | ||
139 | blt.b .yuv_no_clamp1 | ||
140 | move.l %d1,%d7 | ||
141 | .yuv_no_clamp1: | ||
142 | /* : %d5 = R, %d6 = G, %d7 = B */ | ||
143 | |||
144 | move.l %d6,%d1 /* save g for lower 9 bits */ | ||
145 | lsl.l #3,%d5 /* R << 3 */ | ||
146 | lsr.l #3,%d1 /* G >> 3 */ | ||
147 | or.l %d5,%d1 | ||
148 | move.w %d1,(%a0) /* |00000000|000000000|0000000r|rrrrrggg| */ | ||
149 | lsl.l #6,%d6 /* B << 6 */ | ||
150 | or.l %d6,%d7 /* |00000000|000000000|0000gggg|ggbbbbbb| */ | ||
151 | move.w %d7,(%a0) | ||
152 | |||
153 | /** Write second pixel **/ | ||
154 | clr %d1 | ||
155 | move.b (%a1)+,%d1 /* get y component */ | ||
156 | subq.l #8,%d1 | ||
157 | subq.l #8,%d1 | ||
158 | moveq.l #74,%d6 | ||
159 | muls.w %d6,%d1 | ||
160 | asr.l #8,%d1 | ||
161 | /* : %d1 = Y, %d2 = bu, %d3 = guv, %d4 = rv */ | ||
162 | |||
163 | /* Add Y + each chroma component (can clobber %d2-%d4 values now) */ | ||
164 | add.l %d1,%d4 /* get r */ | ||
165 | add.l %d1,%d3 /* get g */ | ||
166 | add.l %d1,%d2 /* get b */ | ||
167 | |||
168 | move.l %d2,%d1 /* is clamping needed? */ | ||
169 | or.l %d3,%d1 | ||
170 | or.l %d4,%d1 | ||
171 | asr.l #6,%d1 | ||
172 | beq.b .yuv_no_clamp2 /* values in range: skip clamping */ | ||
173 | bpl.b .yuv_r63_test2 /* no negative values: skip to high bounds checks */ | ||
174 | .yuv_r0_test2: | ||
175 | clr.l %d1 /* check for any values < 0 */ | ||
176 | cmp.l %d1,%d4 | ||
177 | bgt.b .yuv_g0_test2 | ||
178 | clr.l %d4 | ||
179 | .yuv_g0_test2: | ||
180 | cmp.l %d1,%d3 | ||
181 | bgt.b .yuv_b0_test2 | ||
182 | clr.l %d3 | ||
183 | .yuv_b0_test2: | ||
184 | cmp.l %d1,%d2 | ||
185 | bgt.b .yuv_r63_test2 | ||
186 | clr.l %d2 | ||
187 | .yuv_r63_test2: /* check for any values > 63 */ | ||
188 | moveq.l #63,%d1 | ||
189 | cmp.l %d1,%d4 | ||
190 | blt.b .yuv_g63_test2 | ||
191 | move.l %d1,%d4 | ||
192 | .yuv_g63_test2: | ||
193 | cmp.l %d1,%d3 | ||
194 | blt.b .yuv_b63_test2 | ||
195 | move.l %d1,%d3 | ||
196 | .yuv_b63_test2: | ||
197 | cmp.l %d1,%d2 | ||
198 | blt.b .yuv_no_clamp2 | ||
199 | move.l %d1,%d2 | ||
200 | .yuv_no_clamp2: | ||
201 | /* : %d4 = R, %d3 = G, %d2 = B */ | ||
202 | |||
203 | move.l %d3,%d1 /* save g for lower 9 bits */ | ||
204 | lsl.l #3,%d4 /* R << 3 */ | ||
205 | lsr.l #3,%d1 /* G >> 3 */ | ||
206 | or.l %d4,%d1 /* |00000000|000000000|0000000r|rrrrrggg| */ | ||
207 | move.w %d1,(%a0) | ||
208 | lsl.l #6,%d3 /* G << 6 */ | ||
209 | or.l %d3,%d2 /* |00000000|000000000|0000gggg|ggbbbbbb| */ | ||
210 | move.w %d2,(%a0) | ||
211 | |||
212 | cmp.l %a1,%a5 /* run %a1 up to end of line */ | ||
213 | bhi.w .yuv_line_loop1 | ||
214 | |||
215 | /* Rewind chroma pointers */ | ||
216 | move.l (40+8,%sp),%a2 /* bu data */ | ||
217 | move.l (40+12,%sp),%a3 /* guv data */ | ||
218 | move.l (40+16,%sp),%a4 /* rv data */ | ||
219 | lea.l (%a5,%d0),%a5 /* next end address */ | ||
220 | |||
221 | .yuv_line_loop2: | ||
222 | clr %d1 | ||
223 | move.b (%a1)+,%d1 /* get y component */ | ||
224 | subq.l #8,%d1 | ||
225 | subq.l #8,%d1 | ||
226 | moveq.l #74,%d6 | ||
227 | muls.w %d6,%d1 | ||
228 | asr.l #8,%d1 | ||
229 | |||
230 | move.b (%a2)+,%d2 /* read save chromas and sign extend */ | ||
231 | extb.l %d2 | ||
232 | move.b (%a3)+,%d3 | ||
233 | extb.l %d3 | ||
234 | move.b (%a4)+,%d4 | ||
235 | extb.l %d4 | ||
236 | /* : %d1 = Y, %d2 = bu, %d3 = guv, %d4 = rv */ | ||
237 | |||
238 | move.l %d1,%d5 /* get r */ | ||
239 | add.l %d4,%d5 | ||
240 | move.l %d1,%d6 /* get g */ | ||
241 | add.l %d3,%d6 | ||
242 | move.l %d1,%d7 /* get b */ | ||
243 | add.l %d2,%d7 | ||
244 | |||
245 | move.l %d7,%d1 /* is clamping needed? */ | ||
246 | or.l %d6,%d1 | ||
247 | or.l %d5,%d1 | ||
248 | asr.l #6,%d1 | ||
249 | beq.b .yuv_no_clamp3 /* values in range: skip clamping */ | ||
250 | bpl.b .yuv_r63_test3 /* no negative values: skip to high bounds checks */ | ||
251 | .yuv_r0_test3: | ||
252 | clr.l %d1 /* check for any values < 0 */ | ||
253 | cmp.l %d1,%d5 | ||
254 | bgt.b .yuv_g0_test3 | ||
255 | clr.l %d5 | ||
256 | .yuv_g0_test3: | ||
257 | cmp.l %d1,%d6 | ||
258 | bgt.b .yuv_b0_test3 | ||
259 | clr.l %d6 | ||
260 | .yuv_b0_test3: | ||
261 | cmp.l %d1,%d7 | ||
262 | bgt.b .yuv_r63_test3 | ||
263 | clr.l %d7 | ||
264 | .yuv_r63_test3: /* check for any values > 63 */ | ||
265 | moveq.l #63,%d1 | ||
266 | cmp.l %d1,%d5 | ||
267 | blt.b .yuv_g63_test3 | ||
268 | move.l %d1,%d5 | ||
269 | .yuv_g63_test3: | ||
270 | cmp.l %d1,%d6 | ||
271 | blt.b .yuv_b63_test3 | ||
272 | move.l %d1,%d6 | ||
273 | .yuv_b63_test3: | ||
274 | cmp.l %d1,%d7 | ||
275 | blt.b .yuv_no_clamp3 | ||
276 | move.l %d1,%d7 | ||
277 | .yuv_no_clamp3: | ||
278 | /* : %d5 = R, %d6 = G, %d7 = B */ | ||
279 | |||
280 | move.l %d6,%d1 /* save g for lower 9 bits */ | ||
281 | lsl.l #3,%d5 /* R << 3 */ | ||
282 | lsr.l #3,%d1 /* G >> 3 */ | ||
283 | or.l %d5,%d1 | ||
284 | move.w %d1,(%a0) /* |00000000|000000000|0000000r|rrrrrggg| */ | ||
285 | lsl.l #6,%d6 /* B << 6 */ | ||
286 | or.l %d6,%d7 /* |00000000|000000000|0000gggg|ggbbbbbb| */ | ||
287 | move.w %d7,(%a0) | ||
288 | |||
289 | /** Write second pixel **/ | ||
290 | clr %d1 | ||
291 | move.b (%a1)+,%d1 /* get y component */ | ||
292 | subq.l #8,%d1 | ||
293 | subq.l #8,%d1 | ||
294 | moveq.l #74,%d6 | ||
295 | muls.w %d6,%d1 | ||
296 | asr.l #8,%d1 | ||
297 | /* : %d1 = Y, %d2 = bu, %d3 = guv, %d4 = rv */ | ||
298 | |||
299 | /* Add Y + each chroma component (can clobber %d2-%d4 values now) */ | ||
300 | add.l %d1,%d4 /* get r */ | ||
301 | add.l %d1,%d3 /* get g */ | ||
302 | add.l %d1,%d2 /* get b */ | ||
303 | |||
304 | move.l %d2,%d1 /* is clamping needed? */ | ||
305 | or.l %d3,%d1 | ||
306 | or.l %d4,%d1 | ||
307 | asr.l #6,%d1 | ||
308 | beq.b .yuv_no_clamp4 /* values in range: skip clamping */ | ||
309 | bpl.b .yuv_r63_test4 /* no negative values: skip to high bounds checks */ | ||
310 | .yuv_r0_test4: | ||
311 | clr.l %d1 /* check for any values < 0 */ | ||
312 | cmp.l %d1,%d4 | ||
313 | bgt.b .yuv_g0_test4 | ||
314 | clr.l %d4 | ||
315 | .yuv_g0_test4: | ||
316 | cmp.l %d1,%d3 | ||
317 | bgt.b .yuv_b0_test4 | ||
318 | clr.l %d3 | ||
319 | .yuv_b0_test4: | ||
320 | cmp.l %d1,%d2 | ||
321 | bgt.b .yuv_r63_test4 | ||
322 | clr.l %d2 | ||
323 | .yuv_r63_test4: /* check for any values > 63 */ | ||
324 | moveq.l #63,%d1 | ||
325 | cmp.l %d1,%d4 | ||
326 | blt.b .yuv_g63_test4 | ||
327 | move.l %d1,%d4 | ||
328 | .yuv_g63_test4: | ||
329 | cmp.l %d1,%d3 | ||
330 | blt.b .yuv_b63_test4 | ||
331 | move.l %d1,%d3 | ||
332 | .yuv_b63_test4: | ||
333 | cmp.l %d1,%d2 | ||
334 | blt.b .yuv_no_clamp4 | ||
335 | move.l %d1,%d2 | ||
336 | .yuv_no_clamp4: | ||
337 | /* : %d4 = R, %d3 = G, %d2 = B */ | ||
338 | |||
339 | move.l %d3,%d1 /* save g for lower 9 bits */ | ||
340 | lsl.l #3,%d4 /* R << 3 */ | ||
341 | lsr.l #3,%d1 /* G >> 3 */ | ||
342 | or.l %d4,%d1 /* |00000000|000000000|0000000r|rrrrrggg| */ | ||
343 | move.w %d1,(%a0) | ||
344 | lsl.l #6,%d3 /* G << 6 */ | ||
345 | or.l %d3,%d2 /* |00000000|000000000|0000gggg|ggbbbbbb| */ | ||
346 | move.w %d2,(%a0) | ||
347 | |||
348 | cmp.l %a1,%a5 /* run %a0 up to end of line */ | ||
349 | bhi.w .yuv_line_loop2 | ||
350 | |||
351 | movem.l (%sp),%d2-%d7/%a2-%a5 | ||
352 | lea.l (40,%sp),%sp /* restore registers */ | ||
353 | |||
354 | rts | ||
355 | /* end lcd_write_yuv420_lines */ | ||
356 | |||
357 | |||
358 | /* begin lcd_write_data */ | ||
26 | .align 2 | 359 | .align 2 |
27 | .global lcd_write_data | 360 | .global lcd_write_data |
28 | .type lcd_write_data,@function | 361 | .type lcd_write_data,@function |
29 | |||
30 | lcd_write_data: | 362 | lcd_write_data: |
31 | move.l (4,%sp),%a0 /* data pointer */ | 363 | move.l (4,%sp),%a0 /* data pointer */ |
32 | move.l (8,%sp),%d0 /* length in words */ | 364 | move.l (8,%sp),%d0 /* length in words */ |