diff options
Diffstat (limited to 'firmware/target/arm/lcd-as-memframe.S')
-rw-r--r-- | firmware/target/arm/lcd-as-memframe.S | 554 |
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 | ||
37 | lcd_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 | ||
41 | 10: @ 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 | ||
51 | 20: @ 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 } @ | ||
88 | 25: @ copy up done @ | ||
89 | ble 40f @ finish line @ no 32-byte segments remaining? | ||
90 | 30: @ 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 @ | ||
95 | 40: @ 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 | ||
129 | lcd_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 @ | ||
140 | 10: @ 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 @ | ||
185 | 15: @ 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 @ | ||
214 | 15: @ 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 @ | ||
243 | 15: @ 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 @ | ||
272 | 15: @ 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 | ||
319 | lcd_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 | ||
337 | 10: @ 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 @ | ||
399 | 15: @ 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 @ | ||
445 | 15: @ 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 @ | ||
493 | 15: @ 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 @ | ||
539 | 15: @ 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 | ||