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