summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2010-04-05 07:47:31 +0000
committerRafaël Carré <rafael.carre@gmail.com>2010-04-05 07:47:31 +0000
commiteefdd430f1d29db7d98f40e1ad20f75c676e1fb0 (patch)
treed585c418f2d983b6041ac81ed3a2d39e3243632b
parent0f951b1de817eaf311a6d2bc949865cc80c61201 (diff)
downloadrockbox-eefdd430f1d29db7d98f40e1ad20f75c676e1fb0.tar.gz
rockbox-eefdd430f1d29db7d98f40e1ad20f75c676e1fb0.zip
Fuzev2: YUV output adapted from Fuzev1
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25479 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/target/arm/as3525/sansa-fuzev2/lcd-as-fuzev2.S530
-rw-r--r--firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c2
3 files changed, 533 insertions, 1 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index fe97fe2253..2ee04f2815 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1303,7 +1303,7 @@ target/arm/as3525/sansa-fuze/powermgmt-fuze.c
1303#ifdef SANSA_FUZEV2 1303#ifdef SANSA_FUZEV2
1304#ifndef SIMULATOR 1304#ifndef SIMULATOR
1305target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c 1305target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c
1306target/arm/as3525/lcd-as-e200v2-fuze.S 1306target/arm/as3525/sansa-fuzev2/lcd-as-fuzev2.S
1307target/arm/as3525/sansa-fuzev2/backlight-fuzev2.c 1307target/arm/as3525/sansa-fuzev2/backlight-fuzev2.c
1308target/arm/as3525/sansa-fuzev2/button-fuzev2.c 1308target/arm/as3525/sansa-fuzev2/button-fuzev2.c
1309#ifndef BOOTLOADER 1309#ifndef BOOTLOADER
diff --git a/firmware/target/arm/as3525/sansa-fuzev2/lcd-as-fuzev2.S b/firmware/target/arm/as3525/sansa-fuzev2/lcd-as-fuzev2.S
new file mode 100644
index 0000000000..c760eea30a
--- /dev/null
+++ b/firmware/target/arm/as3525/sansa-fuzev2/lcd-as-fuzev2.S
@@ -0,0 +1,530 @@
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 * Adapted for Sansa Fuzev2 by Rafaël Carré
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#include "config.h"
25#include "cpu.h"
26
27#define DBOP_BUSY (1<<10)
28
29/****************************************************************************
30 * void lcd_write_yuv_420_lines(unsigned char const * const src[3],
31 * int width,
32 * int stride);
33 *
34 * |R| |1.000000 -0.000001 1.402000| |Y'|
35 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
36 * |B| |1.000000 1.772000 0.000000| |Pr|
37 * Scaled, normalized, rounded and tweaked to yield RGB 565:
38 * |R| |74 0 101| |Y' - 16| >> 9
39 * |G| = |74 -24 -51| |Cb - 128| >> 8
40 * |B| |74 128 0| |Cr - 128| >> 9
41 *
42 * Write four RGB565 pixels in the following order on each loop:
43 * 1 3 + > down
44 * 2 4 \/ left
45 */
46 .section .icode, "ax", %progbits
47 .align 2
48 .global lcd_write_yuv420_lines
49 .type lcd_write_yuv420_lines, %function
50lcd_write_yuv420_lines:
51 @ r0 = yuv_src
52 @ r1 = width
53 @ r2 = stride
54 stmfd sp!, { r4-r11, lr } @ save non-scratch
55
56 mov r3, #0xC8000000 @
57 orr r3, r3, #0x120000 @ r3 = DBOP_BASE
58
59 ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
60 @ r5 = yuv_src[1] = Cb_p
61 @ r6 = yuv_src[2] = Cr_p
62 @ r0 = scratch
63
64 sub r2, r2, #1 @ stride -= 1
65
6610: @ loop line @
67 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
68 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
69 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
70 @
71 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
72 add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
73 add r7, r12, r7, asl #5 @ by one less when adding - same for all
74 @
75 sub r8, r8, #128 @ Cb -= 128
76 sub r9, r9, #128 @ Cr -= 128
77 @
78 add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
79 add r10, r10, r10, asl #4 @
80 add r10, r10, r8, asl #3 @
81 add r10, r10, r8, asl #4 @
82 @
83 add lr, r9, r9, asl #2 @ r9 = Cr*101
84 add lr, lr, r9, asl #5 @
85 add r9, lr, r9, asl #6 @
86 @
87 add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
88 mov r8, r8, asr #2 @
89 add r9, r9, #256 @ r9 = rv = (r9 + 256) >> 9
90 mov r9, r9, asr #9 @
91 rsb r10, r10, #128 @ r10 = guv = (-r10 + 128) >> 8
92 mov r10, r10, asr #8 @
93 @ compute R, G, and B
94 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
95 add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
96 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
97 @
98 orr r12, r0, lr @ check if clamping is needed...
99 orr r12, r12, r7, asr #1 @ ...at all
100 cmp r12, #31 @
101 bls 15f @ no clamp @
102 cmp r0, #31 @ clamp b
103 mvnhi r0, r0, asr #31 @
104 andhi r0, r0, #31 @
105 cmp lr, #31 @ clamp r
106 mvnhi lr, lr, asr #31 @
107 andhi lr, lr, #31 @
108 cmp r7, #63 @ clamp g
109 mvnhi r7, r7, asr #31 @
110 andhi r7, r7, #63 @
11115: @ no clamp @
112 @
113 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
114 @
115 orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
116 orr r11, r0, r7, lsl #5 @ r11 = (r << 11) | (g << 5) | b
117 @
118 mov r0, r11, lsr #8 @
119 bic r11, r11, #0xff00 @
120 orr r11, r0, r11, lsl #8 @ swap bytes
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 orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
148 orr r0, r0, r7, lsl #5 @ r0 = (r << 11) | (g << 5) | b
149 @
150 mov r7, r0, lsr #8 @
151 bic r7, r7, #0xff00 @
152 orr r0, r7, r0, lsl #8 @ swap bytes
153 @
154 orr r0, r11, r0, lsl#16 @ pack with 2nd pixel
155 str r0, [r3, #0x10] @ write pixel
156 @
157 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
158 add r12, r7, r7, asl #2 @
159 add r7, r12, r7, asl #5 @
160 @ compute R, G, and B
161 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
162 add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
163 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
164 @
165 orr r12, r0, lr @ check if clamping is needed...
166 orr r12, r12, r7, asr #1 @ ...at all
167 cmp r12, #31 @
168 bls 15f @ no clamp @
169 cmp r0, #31 @ clamp b
170 mvnhi r0, r0, asr #31 @
171 andhi r0, r0, #31 @
172 cmp lr, #31 @ clamp r
173 mvnhi lr, lr, asr #31 @
174 andhi lr, lr, #31 @
175 cmp r7, #63 @ clamp g
176 mvnhi r7, r7, asr #31 @
177 andhi r7, r7, #63 @
17815: @ no clamp @
179 @
180 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
181 @
182 @
183 orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
184 orr r11, r0, r7, lsl #5 @ r0 = (r << 11) | (g << 5) | b
185 @
186 mov r0, r11, lsr #8 @
187 bic r11, r11, #0xff00 @
188 orr r11, r0, r11, lsl #8 @ swap bytes
189 @
190 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
191 add r12, r7, r7, asl #2 @
192 add r7, r12, r7, asl #5 @
193 @ compute R, G, and B
194 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
195 add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
196 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
197 @
198 orr r12, r0, lr @ check if clamping is needed...
199 orr r12, r12, r7, asr #1 @ ...at all
200 cmp r12, #31 @
201 bls 15f @ no clamp @
202 cmp r0, #31 @ clamp b
203 mvnhi r0, r0, asr #31 @
204 andhi r0, r0, #31 @
205 cmp lr, #31 @ clamp r
206 mvnhi lr, lr, asr #31 @
207 andhi lr, lr, #31 @
208 cmp r7, #63 @ clamp g
209 mvnhi r7, r7, asr #31 @
210 andhi r7, r7, #63 @
21115: @ no clamp @
212 @
213 orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
214 orr r0, r0, r7, lsl #5 @ r0 = (r << 11) | (g << 5) | b
215 @
216 mov r7, r0, lsr #8 @
217 bic r7, r7, #0xff00 @
218 orr r0, r7, r0, lsl #8 @ swap bytes
219 @
220 orr r0, r11, r0, lsl#16 @ pack with 2nd pixel
221 str r0, [r3, #0x10] @ write pixel
222 @
223 subs r1, r1, #2 @ subtract block from width
224 bgt 10b @ loop line @
225 @
2261: @ busy
227 @ writing at max 110*32 its (LCD_WIDTH/2), the fifo is bigger
228 @ so polling fifo empty after the loops is save
229 ldr r7, [r3,#0xc] @ r7 = DBOP_STATUS
230 tst r7, #DBOP_BUSY @ fifo not empty?
231 beq 1b @
232
233 ldmfd sp!, { r4-r11, pc } @ restore registers and return
234 bx lr @
235 .ltorg @ dump constant pool
236 .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
237
238/****************************************************************************
239 * void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3],
240 * int width,
241 * int stride,
242 * int x_screen,
243 * int y_screen);
244 *
245 * |R| |1.000000 -0.000001 1.402000| |Y'|
246 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
247 * |B| |1.000000 1.772000 0.000000| |Pr|
248 * Red scaled at twice g & b but at same precision to place it in correct
249 * bit position after multiply and leave instruction count lower.
250 * |R| |258 0 408| |Y' - 16|
251 * |G| = |149 -49 -104| |Cb - 128|
252 * |B| |149 258 0| |Cr - 128|
253 *
254 * Write four RGB565 pixels in the following order on each loop:
255 * 1 3 + > down
256 * 2 4 \/ left
257 *
258 * Kernel pattern (raw|rotated|use order):
259 * 5 3 4 2 2 6 3 7 row0 row2 > down
260 * 1 7 0 6 | 4 0 5 1 | 2 4 6 0 3 5 7 1 col0 left
261 * 4 2 5 3 | 3 7 2 6 | 3 5 7 1 2 4 6 0 col2 \/
262 * 0 6 1 7 5 1 4 0
263 */
264 .section .icode, "ax", %progbits
265 .align 2
266 .global lcd_write_yuv420_lines_odither
267 .type lcd_write_yuv420_lines_odither, %function
268lcd_write_yuv420_lines_odither:
269 @ r0 = yuv_src
270 @ r1 = width
271 @ r2 = stride
272 @ r3 = x_screen
273 @ [sp] = y_screen
274 stmfd sp!, { r4-r11, lr } @ save non-scratch
275 ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
276 @ r5 = yuv_src[1] = Cb_p
277 @ r6 = yuv_src[2] = Cr_p
278 @
279 ldr r14, [sp, #40] @ Line up pattern and kernel quadrant
280 sub r2, r2, #1 @ stride =- 1
281 eor r14, r14, r3 @
282 and r14, r14, #0x2 @
283 mov r14, r14, lsl #6 @ 0x00 or 0x80
284
285 mov r3, #0xC8000000 @
286 orr r3, r3, #0x120000 @ r3 = DBOP_BASE, need to be redone
287 @ due to lack of registers
28810: @ loop line @
289 @
290 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
291 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
292 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
293 @
294 eor r14, r14, #0x80 @ flip pattern quadrant
295 @
296 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
297 add r12, r7, r7, asl #2 @
298 add r12, r12, r12, asl #4 @
299 add r7, r12, r7, asl #6 @
300 @
301 sub r8, r8, #128 @ Cb -= 128
302 sub r9, r9, #128 @ Cr -= 128
303 @
304 add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
305 add r10, r10, r8, asl #5 @
306 add r10, r10, r9, asl #3 @
307 add r10, r10, r9, asl #5 @
308 add r10, r10, r9, asl #6 @
309 @
310 mov r8, r8, asl #1 @ r8 = bu = Cb*258
311 add r8, r8, r8, asl #7 @
312 @
313 add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
314 add r9, r9, r9, asl #4 @
315 mov r9, r9, asl #3 @
316 @
317 @ compute R, G, and B
318 add r0, r8, r7 @ r0 = b' = Y + bu
319 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
320 rsb r7, r10, r7 @ r7 = g' = Y + guv
321 @
322 @ r8 = bu, r9 = rv, r10 = guv
323 @
324 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
325 add r0, r12, r0, lsr #8 @
326 @
327 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
328 add r11, r12, r11, lsr #8 @
329 @
330 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
331 add r7, r12, r7, lsr #8 @
332 @
333 add r12, r14, #0x100 @
334 @
335 add r0, r0, r12 @ b = r0 + delta
336 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
337 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
338 @
339 orr r12, r0, r11, asr #1 @ check if clamping is needed...
340 orr r12, r12, r7 @ ...at all
341 movs r12, r12, asr #15 @
342 beq 15f @ no clamp @
343 movs r12, r0, asr #15 @ clamp b
344 mvnne r0, r12, lsr #15 @
345 andne r0, r0, #0x7c00 @ mask b only if clamped
346 movs r12, r11, asr #16 @ clamp r
347 mvnne r11, r12, lsr #16 @
348 movs r12, r7, asr #15 @ clamp g
349 mvnne r7, r12, lsr #15 @
35015: @ no clamp @
351 @
352 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
353 @
354 and r11, r11, #0xf800 @ pack pixel
355 and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
356 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
357 orr r3, r11, r0, lsr #10 @ (b >> 10)
358 @
359 mov r7, r3, lsr #8 @
360 bic r3, r3, #0xff00 @
361 orr r3, r7, r3, lsl #8 @ swap pixel
362 @ save pixel
363 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
364 add r12, r7, r7, asl #2 @
365 add r12, r12, r12, asl #4 @
366 add r7, r12, r7, asl #6 @
367 @ compute R, G, and B
368 add r0, r8, r7 @ r0 = b' = Y + bu
369 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
370 rsb r7, r10, r7 @ r7 = g' = Y + guv
371 @
372 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
373 add r0, r12, r0, lsr #8 @
374 @
375 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
376 add r11, r12, r11, lsr #8 @
377 @
378 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
379 add r7, r12, r7, lsr #8 @
380 @
381 add r12, r14, #0x200 @
382 @
383 add r0, r0, r12 @ b = r0 + delta
384 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
385 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
386 @
387 orr r12, r0, r11, asr #1 @ check if clamping is needed...
388 orr r12, r12, r7 @ ...at all
389 movs r12, r12, asr #15 @
390 beq 15f @ no clamp @
391 movs r12, r0, asr #15 @ clamp b
392 mvnne r0, r12, lsr #15 @
393 andne r0, r0, #0x7c00 @ mask b only if clamped
394 movs r12, r11, asr #16 @ clamp r
395 mvnne r11, r12, lsr #16 @
396 movs r12, r7, asr #15 @ clamp g
397 mvnne r7, r12, lsr #15 @
39815: @ no clamp @
399 @
400 ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
401
402 and r11, r11, #0xf800 @ pack pixel
403 and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
404 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
405 orr r0, r11, r0, lsr #10 @ (b >> 10)
406 @
407 mov r7, r0, lsr #8 @
408 bic r0, r0, #0xff00 @
409 orr r0, r7, r0, lsl #8 @ swap pixel
410 orr r3, r3, r0, lsl#16 @ pack with 2nd pixel
411 mov r0, #0xC8000000 @
412 orr r0, r0, #0x120000 @ r3 = DBOP_BASE
413
414 str r3, [r0, #0x10] @ write pixel
415 @
416 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
417 add r12, r7, r7, asl #2 @
418 add r12, r12, r12, asl #4 @
419 add r7, r12, r7, asl #6 @
420 @ compute R, G, and B
421 add r0, r8, r7 @ r0 = b' = Y + bu
422 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
423 rsb r7, r10, r7 @ r7 = g' = Y + guv
424 @
425 @ r8 = bu, r9 = rv, r10 = guv
426 @
427 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
428 add r0, r12, r0, lsr #8 @
429 @
430 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
431 add r11, r12, r11, lsr #8 @
432 @
433 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
434 add r7, r12, r7, lsr #8 @
435 @
436 add r12, r14, #0x300 @
437 @
438 add r0, r0, r12 @ b = r0 + delta
439 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
440 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
441 @
442 orr r12, r0, r11, asr #1 @ check if clamping is needed...
443 orr r12, r12, r7 @ ...at all
444 movs r12, r12, asr #15 @
445 beq 15f @ no clamp @
446 movs r12, r0, asr #15 @ clamp b
447 mvnne r0, r12, lsr #15 @
448 andne r0, r0, #0x7c00 @ mask b only if clamped
449 movs r12, r11, asr #16 @ clamp r
450 mvnne r11, r12, lsr #16 @
451 movs r12, r7, asr #15 @ clamp g
452 mvnne r7, r12, lsr #15 @
45315: @ no clamp @
454 @
455 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
456 @
457 and r11, r11, #0xf800 @ pack pixel
458 and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
459 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
460 orr r3, r11, r0, lsr #10 @ (b >> 10)
461 @
462 mov r7, r3, lsr #8 @
463 bic r3, r3, #0xff00 @
464 orr r3, r7, r3, lsl #8 @ swap pixel
465 @ save pixel
466 @
467 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
468 add r12, r7, r7, asl #2 @
469 add r12, r12, r12, asl #4 @
470 add r7, r12, r7, asl #6 @
471 @ compute R, G, and B
472 add r0, r8, r7 @ r0 = b' = Y + bu
473 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
474 rsb r7, r10, r7 @ r7 = g' = Y + guv
475 @
476 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
477 add r0, r12, r0, lsr #8 @
478 @
479 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
480 add r11, r12, r11, lsr #8 @
481 @
482 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
483 add r7, r12, r7, lsr #8 @
484 @
485 @ This element is zero - use r14 @
486 @
487 add r0, r0, r14 @ b = r0 + delta
488 add r11, r11, r14, lsl #1 @ r = r11 + delta*2
489 add r7, r7, r14, lsr #1 @ g = r7 + delta/2
490 @
491 orr r12, r0, r11, asr #1 @ check if clamping is needed...
492 orr r12, r12, r7 @ ...at all
493 movs r12, r12, asr #15 @
494 beq 15f @ no clamp @
495 movs r12, r0, asr #15 @ clamp b
496 mvnne r0, r12, lsr #15 @
497 andne r0, r0, #0x7c00 @ mask b only if clamped
498 movs r12, r11, asr #16 @ clamp r
499 mvnne r11, r12, lsr #16 @
500 movs r12, r7, asr #15 @ clamp g
501 mvnne r7, r12, lsr #15 @
50215: @ no clamp @
503 @
504 and r11, r11, #0xf800 @ pack pixel
505 and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
506 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
507 orr r0, r11, r0, lsr #10 @ (b >> 10)
508 @
509 mov r7, r0, lsr #8 @
510 bic r0, r0, #0xff00 @
511 orr r0, r7, r0, lsl #8 @ swap pixel
512 orr r3, r3, r0, lsl#16 @ pack with 2nd pixel
513 mov r0, #0xC8000000 @
514 orr r0, r0, #0x120000 @ r3 = DBOP_BASE
515
516 str r3, [r0, #0x10] @ write pixel
517 @
518 subs r1, r1, #2 @ subtract block from width
519 bgt 10b @ loop line @
520 @
5211: @ busy @
522 @ writing at max 110*32 its (LCD_WIDTH/2), the fifo is bigger
523 @ so polling fifo empty after the loops is save
524 ldr r7, [r0,#0xc] @ r7 = DBOP_STATUS
525 tst r7, #DBOP_BUSY @ fifo not empty?
526 beq 1b @
527
528 ldmfd sp!, { r4-r11, pc } @ restore registers and return
529 .ltorg @ dump constant pool
530 .size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
diff --git a/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c b/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c
index 618d242c4a..5fa26c0eaf 100644
--- a/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c
+++ b/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c
@@ -404,6 +404,7 @@ void lcd_blit_yuv(unsigned char * const src[3],
404 404
405 lcd_write_cmd(R_WRITE_DATA_2_GRAM); 405 lcd_write_cmd(R_WRITE_DATA_2_GRAM);
406 406
407 dbop_set_mode(32);
407 lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y); 408 lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y);
408 yuv_src[0] += stride << 1; /* Skip down two luma lines */ 409 yuv_src[0] += stride << 1; /* Skip down two luma lines */
409 yuv_src[1] += stride >> 1; /* Skip down one chroma line */ 410 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
@@ -420,6 +421,7 @@ void lcd_blit_yuv(unsigned char * const src[3],
420 421
421 lcd_write_cmd(R_WRITE_DATA_2_GRAM); 422 lcd_write_cmd(R_WRITE_DATA_2_GRAM);
422 423
424 dbop_set_mode(32);
423 lcd_write_yuv420_lines(yuv_src, width, stride); 425 lcd_write_yuv420_lines(yuv_src, width, stride);
424 yuv_src[0] += stride << 1; /* Skip down two luma lines */ 426 yuv_src[0] += stride << 1; /* Skip down two luma lines */
425 yuv_src[1] += stride >> 1; /* Skip down one chroma line */ 427 yuv_src[1] += stride >> 1; /* Skip down one chroma line */