summaryrefslogtreecommitdiff
path: root/firmware/target/arm/lcd-as-memframe.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/lcd-as-memframe.S')
-rw-r--r--firmware/target/arm/lcd-as-memframe.S554
1 files changed, 554 insertions, 0 deletions
diff --git a/firmware/target/arm/lcd-as-memframe.S b/firmware/target/arm/lcd-as-memframe.S
new file mode 100644
index 0000000000..7071bec7ac
--- /dev/null
+++ b/firmware/target/arm/lcd-as-memframe.S
@@ -0,0 +1,554 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Michael Sevakis
11 *
12 * ARM code for memory framebuffer LCDs
13 *
14 * All files in this archive are subject to the GNU General Public License.
15 * See the file COPYING in the source tree root for full license agreement.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include "cpu.h"
24
25/****************************************************************************
26 * void lcd_copy_buffer_rect(fb_data *dst, fb_data *src, int width,
27 * int height);
28 */
29 .section .icode, "ax", %progbits
30 .align 2
31 .global lcd_copy_buffer_rect
32 .type lcd_copy_buffer_rect, %function
33 @ r0 = dst
34 @ r1 = src
35 @ r2 = width
36 @ r3 = height
37lcd_copy_buffer_rect: @
38 stmfd sp!, { r4-r12, lr } @ save non-scratch regs
39 mov r5, r2 @ r5 = cached width
40 rsb r4, r2, #LCD_WIDTH @ r4 = LCD_WIDTH - width
4110: @ copy line @
42 subs r2, r5, #1 @ r2 = width - 1
43 beq 40f @ finish line @ one halfword? skip to trailing copy
44 tst r0, #2 @ word aligned?
45 beq 20f @ rem copy @ yes? skip to word copy
46 ldrh r6, [r1], #2 @ copy leading halfword
47 subs r2, r2, #1 @
48 strh r6, [r0], #2 @
49 ble 40f @ finish line @ next line if lt or finish
50 @ trailing halfword if eq
5120: @ rem copy @
52 add r14, r2, #1 @ get remaining width mod 16 after word
53 @ align (rw)
54 and r14, r14, #0xe @ r14 = 0 (16), 2, 4, 6, 8, 10, 12, 14
55 add pc, pc, r14, lsl #3 @ branch to 32-byte align
56 nop @
57 b 30f @ rw % 16 = 0 or 1? use octword loop
58 nop @
59 nop @
60 nop @
61 ldr r6, [r1], #4 @ rw % 16 = 2 or 3
62 subs r2, r2, #2 @
63 str r6, [r0], #4 @
64 b 25f @ copy up done @
65 ldmia r1!, { r6-r7 } @ rw % 16 = 4 or 5
66 subs r2, r2, #4 @
67 stmia r0!, { r6-r7 } @
68 b 25f @ copy up done @
69 ldmia r1!, { r6-r8 } @ rw % 16 = 6 or 7
70 subs r2, r2, #6 @
71 stmia r0!, { r6-r8 } @
72 b 25f @ copy up done @
73 ldmia r1!, { r6-r9 } @ rw % 16 = 8 or 9
74 subs r2, r2, #8 @
75 stmia r0!, { r6-r9 } @
76 b 25f @ copy up done @
77 ldmia r1!, { r6-r10 } @ rw % 16 = 10 or 11
78 subs r2, r2, #10 @
79 stmia r0!, { r6-r10 } @
80 b 25f @ copy up done @
81 ldmia r1!, { r6-r11 } @ rw % 16 = 12 or 13
82 subs r2, r2, #12 @
83 stmia r0!, { r6-r11 } @
84 b 25f @ copy up done @
85 ldmia r1!, { r6-r12 } @ rw % 16 = 14 or 15
86 subs r2, r2, #14 @
87 stmia r0!, { r6-r12 } @
8825: @ copy up done @
89 ble 40f @ finish line @ no 32-byte segments remaining?
9030: @ octword loop @ copy 16 pixels per loop
91 ldmia r1!, { r6-r12, r14 } @
92 subs r2, r2, #16 @
93 stmia r0!, { r6-r12, r14 } @
94 bgt 30b @ octword loop @
9540: @ finish line @
96 ldreqh r6, [r1], #2 @ finish last halfword if eq ...
97 add r1, r1, r4, lsl #1 @
98 streqh r6, [r0], #2 @ ...
99 add r0, r0, r4, lsl #1 @
100 subs r3, r3, #1 @ next line
101 bgt 10b @ copy line @
102 ldmfd sp!, { r4-r12, pc } @ restore regs and return
103 .ltorg @ dump constant pool
104 .size lcd_copy_buffer_rect, .-lcd_copy_buffer_rect
105
106
107/****************************************************************************
108 * void lcd_write_yuv_420_lines(fb_data *dst,
109 * unsigned char const * const src[3],
110 * int width,
111 * int stride);
112 *
113 * |R| |1.000000 -0.000001 1.402000| |Y'|
114 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
115 * |B| |1.000000 1.772000 0.000000| |Pr|
116 * Scaled, normalized, rounded and tweaked to yield RGB 565:
117 * |R| |74 0 101| |Y' - 16| >> 9
118 * |G| = |74 -24 -51| |Cb - 128| >> 8
119 * |B| |74 128 0| |Cr - 128| >> 9
120 *
121 * Write four RGB565 pixels in the following order on each loop:
122 * 1 3 + > down
123 * 2 4 \/ left
124 */
125 .section .icode, "ax", %progbits
126 .align 2
127 .global lcd_write_yuv420_lines
128 .type lcd_write_yuv420_lines, %function
129lcd_write_yuv420_lines:
130 @ r0 = dst
131 @ r1 = yuv_src
132 @ r2 = width
133 @ r3 = stride
134 stmfd sp!, { r4-r12 } @ save non-scratch
135 ldmia r1, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
136 @ r5 = yuv_src[1] = Cb_p
137 @ r6 = yuv_src[2] = Cr_p
138 @ r1 = scratch
139 sub r3, r3, #1 @
14010: @ loop line @
141 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
142 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
143 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
144 @
145 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
146 add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
147 add r7, r12, r7, asl #5 @ by one less when adding - same for all
148 @
149 sub r8, r8, #128 @ Cb -= 128
150 sub r9, r9, #128 @ Cr -= 128
151 @
152 add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
153 add r10, r10, r10, asl #4 @
154 add r10, r10, r8, asl #3 @
155 add r10, r10, r8, asl #4 @
156 @
157 add r11, r9, r9, asl #2 @ r9 = Cr*101
158 add r11, r11, r9, asl #5 @
159 add r9, r11, r9, asl #6 @
160 @
161 add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
162 mov r8, r8, asr #2 @
163 add r9, r9, #256 @ r9 = rv = (r9 + 256) >> 9
164 mov r9, r9, asr #9 @
165 rsb r10, r10, #128 @ r10 = guv = (-r10 + 128) >> 8
166 mov r10, r10, asr #8 @
167 @ compute R, G, and B
168 add r1, r8, r7, asr #8 @ r1 = b = (Y >> 9) + bu
169 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
170 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
171 @
172 orr r12, r1, r11 @ check if clamping is needed...
173 orr r12, r12, r7, asr #1 @ ...at all
174 cmp r12, #31 @
175 bls 15f @ no clamp @
176 cmp r1, #31 @ clamp b
177 mvnhi r1, r1, asr #31 @
178 andhi r1, r1, #31 @
179 cmp r11, #31 @ clamp r
180 mvnhi r11, r11, asr #31 @
181 andhi r11, r11, #31 @
182 cmp r7, #63 @ clamp g
183 mvnhi r7, r7, asr #31 @
184 andhi r7, r7, #63 @
18515: @ no clamp @
186 @
187 ldrb r12, [r4, r3] @ r12 = Y' = *(Y'_p + stride)
188 @
189 orr r1, r1, r7, lsl #5 @ r4 |= (g << 5)
190 orr r1, r1, r11, lsl #11 @ r4 = b | (r << 11)
191 strh r1, [r0], #LCD_WIDTH @ store pixel
192 @
193 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
194 add r12, r7, r7, asl #2 @
195 add r7, r12, r7, asl #5 @
196 @ compute R, G, and B
197 add r1, r8, r7, asr #8 @ r1 = b = (Y >> 9) + bu
198 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
199 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
200 @
201 orr r12, r1, r11 @ check if clamping is needed...
202 orr r12, r12, r7, asr #1 @ ...at all
203 cmp r12, #31 @
204 bls 15f @ no clamp @
205 cmp r1, #31 @ clamp b
206 mvnhi r1, r1, asr #31 @
207 andhi r1, r1, #31 @
208 cmp r11, #31 @ clamp r
209 mvnhi r11, r11, asr #31 @
210 andhi r11, r11, #31 @
211 cmp r7, #63 @ clamp g
212 mvnhi r7, r7, asr #31 @
213 andhi r7, r7, #63 @
21415: @ no clamp @
215 @
216 ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
217 @
218 orr r1, r1, r11, lsl #11 @ r1 = b | (r << 11)
219 orr r1, r1, r7, lsl #5 @ r1 |= (g << 5)
220 strh r1, [r0, #-LCD_WIDTH-2] @ store pixel
221 @
222 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
223 add r12, r7, r7, asl #2 @
224 add r7, r12, r7, asl #5 @
225 @ compute R, G, and B
226 add r1, r8, r7, asr #8 @ r1 = b = (Y >> 9) + bu
227 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
228 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
229 @
230 orr r12, r1, r11 @ check if clamping is needed...
231 orr r12, r12, r7, asr #1 @ ...at all
232 cmp r12, #31 @
233 bls 15f @ no clamp @
234 cmp r1, #31 @ clamp b
235 mvnhi r1, r1, asr #31 @
236 andhi r1, r1, #31 @
237 cmp r11, #31 @ clamp r
238 mvnhi r11, r11, asr #31 @
239 andhi r11, r11, #31 @
240 cmp r7, #63 @ clamp g
241 mvnhi r7, r7, asr #31 @
242 andhi r7, r7, #63 @
24315: @ no clamp @
244 @
245 ldrb r12, [r4, r3] @ r12 = Y' = *(Y'_p + stride)
246 @
247 orr r1, r1, r7, lsl #5 @ r1 = b | (g << 5)
248 orr r1, r1, r11, lsl #11 @ r1 |= (r << 11)
249 strh r1, [r0, #LCD_WIDTH]! @ store pixel
250 @
251 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
252 add r12, r7, r7, asl #2 @
253 add r7, r12, r7, asl #5 @
254 @ compute R, G, and B
255 add r1, r8, r7, asr #8 @ r1 = b = (Y >> 9) + bu
256 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
257 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
258 @
259 orr r12, r1, r11 @ check if clamping is needed...
260 orr r12, r12, r7, asr #1 @ ...at all
261 cmp r12, #31 @
262 bls 15f @ no clamp @
263 cmp r1, #31 @ clamp b
264 mvnhi r1, r1, asr #31 @
265 andhi r1, r1, #31 @
266 cmp r11, #31 @ clamp r
267 mvnhi r11, r11, asr #31 @
268 andhi r11, r11, #31 @
269 cmp r7, #63 @ clamp g
270 mvnhi r7, r7, asr #31 @
271 andhi r7, r7, #63 @
27215: @ no clamp @
273 @
274 orr r12, r1, r11, lsl #11 @ r12 = b | (r << 11)
275 orr r12, r12, r7, lsl #5 @ r12 |= (g << 5)
276 strh r12, [r0, #-2] @ store pixel
277 add r0, r0, #2*LCD_WIDTH @
278 @
279 subs r2, r2, #2 @ subtract block from width
280 bgt 10b @ loop line @
281 @
282 ldmfd sp!, { r4-r12 } @ restore registers and return
283 bx lr @
284 .ltorg @ dump constant pool
285 .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
286
287
288/****************************************************************************
289 * void lcd_write_yuv_420_lines_odither(fb_data *dst,
290 * unsigned char const * const src[3],
291 * int width,
292 * int stride,
293 * int x_screen,
294 * int y_screen);
295 *
296 * |R| |1.000000 -0.000001 1.402000| |Y'|
297 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
298 * |B| |1.000000 1.772000 0.000000| |Pr|
299 * Red scaled at twice g & b but at same precision to place it in correct
300 * bit position after multiply and leave instruction count lower.
301 * |R| |258 0 408| |Y' - 16|
302 * |G| = |149 -49 -104| |Cb - 128|
303 * |B| |149 258 0| |Cr - 128|
304 *
305 * Write four RGB565 pixels in the following order on each loop:
306 * 1 3 + > down
307 * 2 4 \/ left
308 *
309 * Kernel pattern (raw|rotated|use order):
310 * 5 3 4 2 2 6 3 7 row0 row2 > down
311 * 1 7 0 6 | 4 0 5 1 | 2 4 6 0 3 5 7 1 col0 left
312 * 4 2 5 3 | 3 7 2 6 | 3 5 7 1 2 4 6 0 col2 \/
313 * 0 6 1 7 5 1 4 0
314 */
315 .section .icode, "ax", %progbits
316 .align 2
317 .global lcd_write_yuv420_lines_odither
318 .type lcd_write_yuv420_lines_odither, %function
319lcd_write_yuv420_lines_odither:
320 @ r0 = dst
321 @ r1 = yuv_src
322 @ r2 = width
323 @ r3 = stride
324 @ [sp] = x_screen
325 @ [sp+4] = y_screen
326 stmfd sp!, { r4-r12, lr } @ save non-scratch
327 ldmia r1, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
328 @ r5 = yuv_src[1] = Cb_p
329 @ r6 = yuv_src[2] = Cr_p
330 @
331 sub r3, r3, #1 @
332 add r1, sp, #40 @ Line up pattern and kernel quadrant
333 ldmia r1, { r12, r14 } @
334 eor r14, r14, r12 @
335 and r14, r14, #0x2 @
336 mov r14, r14, lsl #6 @ 0x00 or 0x80
33710: @ loop line @
338 @
339 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
340 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
341 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
342 @
343 eor r14, r14, #0x80 @ flip pattern quadrant
344 @
345 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
346 add r12, r7, r7, asl #2 @
347 add r12, r12, r12, asl #4 @
348 add r7, r12, r7, asl #6 @
349 @
350 sub r8, r8, #128 @ Cb -= 128
351 sub r9, r9, #128 @ Cr -= 128
352 @
353 add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
354 add r10, r10, r8, asl #5 @
355 add r10, r10, r9, asl #3 @
356 add r10, r10, r9, asl #5 @
357 add r10, r10, r9, asl #6 @
358 @
359 mov r8, r8, asl #1 @ r8 = bu = Cb*258
360 add r8, r8, r8, asl #7 @
361 @
362 add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
363 add r9, r9, r9, asl #4 @
364 mov r9, r9, asl #3 @
365 @
366 @ compute R, G, and B
367 add r1, r8, r7 @ r1 = b' = Y + bu
368 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
369 rsb r7, r10, r7 @ r7 = g' = Y + guv
370 @
371 @ r8 = bu, r9 = rv, r10 = guv
372 @
373 sub r12, r1, r1, lsr #5 @ r1 = 31/32*b + b/256
374 add r1, r12, r1, lsr #8 @
375 @
376 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
377 add r11, r12, r11, lsr #8 @
378 @
379 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
380 add r7, r12, r7, lsr #8 @
381 @
382 add r12, r14, #0x100 @
383 @
384 add r1, r1, r12 @ b = r1 + delta
385 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
386 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
387 @
388 orr r12, r1, r11, asr #1 @ check if clamping is needed...
389 orr r12, r12, r7 @ ...at all
390 movs r12, r12, asr #15 @
391 beq 15f @ no clamp @
392 movs r12, r1, asr #15 @ clamp b
393 mvnne r1, r12, lsr #15 @
394 andne r1, r1, #0x7c00 @ mask b only if clamped
395 movs r12, r11, asr #16 @ clamp r
396 mvnne r11, r12, lsr #16 @
397 movs r12, r7, asr #15 @ clamp g
398 mvnne r7, r12, lsr #15 @
39915: @ no clamp @
400 @
401 ldrb r12, [r4, r3] @ r12 = Y' = *(Y'_p + stride)
402 @
403 and r11, r11, #0xf800 @ pack pixel
404 and r7, r7, #0x7e00 @ r1 = pixel = (r & 0xf800) |
405 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
406 orr r1, r11, r1, lsr #10 @ (b >> 10)
407 @
408 strh r1, [r0], #LCD_WIDTH @ store pixel
409 @
410 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
411 add r12, r7, r7, asl #2 @
412 add r12, r12, r12, asl #4 @
413 add r7, r12, r7, asl #6 @
414 @ compute R, G, and B
415 add r1, r8, r7 @ r1 = b' = Y + bu
416 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
417 rsb r7, r10, r7 @ r7 = g' = Y + guv
418 @
419 sub r12, r1, r1, lsr #5 @ r1 = 31/32*b' + b'/256
420 add r1, r12, r1, lsr #8 @
421 @
422 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
423 add r11, r12, r11, lsr #8 @
424 @
425 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
426 add r7, r12, r7, lsr #8 @
427 @
428 add r12, r14, #0x200 @
429 @
430 add r1, r1, r12 @ b = r1 + delta
431 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
432 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
433 @
434 orr r12, r1, r11, asr #1 @ check if clamping is needed...
435 orr r12, r12, r7 @ ...at all
436 movs r12, r12, asr #15 @
437 beq 15f @ no clamp @
438 movs r12, r1, asr #15 @ clamp b
439 mvnne r1, r12, lsr #15 @
440 andne r1, r1, #0x7c00 @ mask b only if clamped
441 movs r12, r11, asr #16 @ clamp r
442 mvnne r11, r12, lsr #16 @
443 movs r12, r7, asr #15 @ clamp g
444 mvnne r7, r12, lsr #15 @
44515: @ no clamp @
446 @
447 ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
448 @
449 and r11, r11, #0xf800 @ pack pixel
450 and r7, r7, #0x7e00 @ r1 = pixel = (r & 0xf800) |
451 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
452 orr r1, r11, r1, lsr #10 @ (b >> 10)
453 @
454 strh r1, [r0, #-LCD_WIDTH-2] @ store pixel
455 @
456 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
457 add r12, r7, r7, asl #2 @
458 add r12, r12, r12, asl #4 @
459 add r7, r12, r7, asl #6 @
460 @ compute R, G, and B
461 add r1, r8, r7 @ r1 = b' = Y + bu
462 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
463 rsb r7, r10, r7 @ r7 = g' = Y + guv
464 @
465 @ r8 = bu, r9 = rv, r10 = guv
466 @
467 sub r12, r1, r1, lsr #5 @ r1 = 31/32*b' + b'/256
468 add r1, r12, r1, lsr #8 @
469 @
470 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
471 add r11, r12, r11, lsr #8 @
472 @
473 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
474 add r7, r12, r7, lsr #8 @
475 @
476 add r12, r14, #0x300 @
477 @
478 add r1, r1, r12 @ b = r1 + delta
479 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
480 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
481 @
482 orr r12, r1, r11, asr #1 @ check if clamping is needed...
483 orr r12, r12, r7 @ ...at all
484 movs r12, r12, asr #15 @
485 beq 15f @ no clamp @
486 movs r12, r1, asr #15 @ clamp b
487 mvnne r1, r12, lsr #15 @
488 andne r1, r1, #0x7c00 @ mask b only if clamped
489 movs r12, r11, asr #16 @ clamp r
490 mvnne r11, r12, lsr #16 @
491 movs r12, r7, asr #15 @ clamp g
492 mvnne r7, r12, lsr #15 @
49315: @ no clamp @
494 @
495 ldrb r12, [r4, r3] @ r12 = Y' = *(Y'_p + stride)
496 @
497 and r11, r11, #0xf800 @ pack pixel
498 and r7, r7, #0x7e00 @ r1 = pixel = (r & 0xf800) |
499 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
500 orr r1, r11, r1, lsr #10 @ (b >> 10)
501 @
502 strh r1, [r0, #LCD_WIDTH]! @ store pixel
503 @
504 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
505 add r12, r7, r7, asl #2 @
506 add r12, r12, r12, asl #4 @
507 add r7, r12, r7, asl #6 @
508 @ compute R, G, and B
509 add r1, r8, r7 @ r1 = b' = Y + bu
510 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
511 rsb r7, r10, r7 @ r7 = g' = Y + guv
512 @
513 sub r12, r1, r1, lsr #5 @ r1 = 31/32*b + b/256
514 add r1, r12, r1, lsr #8 @
515 @
516 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
517 add r11, r12, r11, lsr #8 @
518 @
519 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
520 add r7, r12, r7, lsr #8 @
521 @
522 @ This element is zero - use r14 @
523 @
524 add r1, r1, r14 @ b = r1 + delta
525 add r11, r11, r14, lsl #1 @ r = r11 + delta*2
526 add r7, r7, r14, lsr #1 @ g = r7 + delta/2
527 @
528 orr r12, r1, r11, asr #1 @ check if clamping is needed...
529 orr r12, r12, r7 @ ...at all
530 movs r12, r12, asr #15 @
531 beq 15f @ no clamp @
532 movs r12, r1, asr #15 @ clamp b
533 mvnne r1, r12, lsr #15 @
534 andne r1, r1, #0x7c00 @ mask b only if clamped
535 movs r12, r11, asr #16 @ clamp r
536 mvnne r11, r12, lsr #16 @
537 movs r12, r7, asr #15 @ clamp g
538 mvnne r7, r12, lsr #15 @
53915: @ no clamp @
540 @
541 and r11, r11, #0xf800 @ pack pixel
542 and r7, r7, #0x7e00 @ r1 = pixel = (r & 0xf800) |
543 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
544 orr r1, r11, r1, lsr #10 @ (b >> 10)
545 @
546 strh r1, [r0, #-2] @ store pixel
547 add r0, r0, #2*LCD_WIDTH @
548 @
549 subs r2, r2, #2 @ subtract block from width
550 bgt 10b @ loop line @
551 @
552 ldmfd sp!, { r4-r12, pc } @ restore registers and return
553 .ltorg @ dump constant pool
554 .size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither