summaryrefslogtreecommitdiff
path: root/firmware/target/arm/sandisk/sansa-c200/lcd-as-c200.S
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2007-10-21 13:46:26 +0000
committerJens Arnold <amiconn@rockbox.org>2007-10-21 13:46:26 +0000
commitc1051549b93d1905602ba25409cbd8f4a607c3b5 (patch)
tree303c0129884c3c32c6ca1e425b8edd4c9caf3ebc /firmware/target/arm/sandisk/sansa-c200/lcd-as-c200.S
parente1a91b9138148bd33ee0bae72a7367b6282aca7f (diff)
downloadrockbox-c1051549b93d1905602ba25409cbd8f4a607c3b5.tar.gz
rockbox-c1051549b93d1905602ba25409cbd8f4a607c3b5.zip
Implement YUV dithering for c200, and enable the option in mpegplayer.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15246 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/sandisk/sansa-c200/lcd-as-c200.S')
-rw-r--r--firmware/target/arm/sandisk/sansa-c200/lcd-as-c200.S306
1 files changed, 306 insertions, 0 deletions
diff --git a/firmware/target/arm/sandisk/sansa-c200/lcd-as-c200.S b/firmware/target/arm/sandisk/sansa-c200/lcd-as-c200.S
index 9b0cd75bae..aaeb8439b6 100644
--- a/firmware/target/arm/sandisk/sansa-c200/lcd-as-c200.S
+++ b/firmware/target/arm/sandisk/sansa-c200/lcd-as-c200.S
@@ -241,3 +241,309 @@ lcd_write_yuv420_lines:
241 .ltorg @ dump constant pool 241 .ltorg @ dump constant pool
242 .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines 242 .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
243 243
244/****************************************************************************
245 * void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3],
246 * int width,
247 * int stride,
248 * int x_screen,
249 * int y_screen);
250 *
251 * |R| |1.000000 -0.000001 1.402000| |Y'|
252 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
253 * |B| |1.000000 1.772000 0.000000| |Pr|
254 * Red scaled at twice g & b but at same precision to place it in correct
255 * bit position after multiply and leave instruction count lower.
256 * |R| |258 0 408| |Y' - 16|
257 * |G| = |149 -49 -104| |Cb - 128|
258 * |B| |149 258 0| |Cr - 128|
259 *
260 * Write four RGB565 pixels in the following order on each loop:
261 * 1 3 + > down
262 * 2 4 \/ left
263 *
264 * Kernel pattern (raw|rotated|use order):
265 * 5 3 4 2 2 6 3 7 row0 row2 > down
266 * 1 7 0 6 | 4 0 5 1 | 2 4 6 0 3 5 7 1 col0 left
267 * 4 2 5 3 | 3 7 2 6 | 3 5 7 1 2 4 6 0 col2 \/
268 * 0 6 1 7 5 1 4 0
269 */
270 .section .icode, "ax", %progbits
271 .align 2
272 .global lcd_write_yuv420_lines_odither
273 .type lcd_write_yuv420_lines_odither, %function
274lcd_write_yuv420_lines_odither:
275 @ r0 = yuv_src
276 @ r1 = width
277 @ r2 = stride
278 @ r3 = x_screen
279 @ [sp] = y_screen
280 stmfd sp!, { r4-r12, lr } @ save non-scratch
281 ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
282 @ r5 = yuv_src[1] = Cb_p
283 @ r6 = yuv_src[2] = Cr_p
284 @
285 sub r2, r2, #1 @
286 ldr r14, [sp, #40] @ Line up pattern and kernel quadrant
287 eor r14, r14, r3 @
288 and r14, r14, #0x2 @
289 mov r14, r14, lsl #6 @ 0x00 or 0x80
290 mov r3, #0x70000000 @
291 orr r3, r3, #0x3000 @ r3 = LCD1_BASE
29210: @ loop line @
293 @
294 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
295 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
296 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
297 @
298 eor r14, r14, #0x80 @ flip pattern quadrant
299 @
300 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
301 add r12, r7, r7, asl #2 @
302 add r12, r12, r12, asl #4 @
303 add r7, r12, r7, asl #6 @
304 @
305 sub r8, r8, #128 @ Cb -= 128
306 sub r9, r9, #128 @ Cr -= 128
307 @
308 add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
309 add r10, r10, r8, asl #5 @
310 add r10, r10, r9, asl #3 @
311 add r10, r10, r9, asl #5 @
312 add r10, r10, r9, asl #6 @
313 @
314 mov r8, r8, asl #1 @ r8 = bu = Cb*258
315 add r8, r8, r8, asl #7 @
316 @
317 add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
318 add r9, r9, r9, asl #4 @
319 mov r9, r9, asl #3 @
320 @
321 @ compute R, G, and B
322 add r0, r8, r7 @ r0 = b' = Y + bu
323 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
324 rsb r7, r10, r7 @ r7 = g' = Y + guv
325 @
326 @ r8 = bu, r9 = rv, r10 = guv
327 @
328 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
329 add r0, r12, r0, lsr #8 @
330 @
331 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
332 add r11, r12, r11, lsr #8 @
333 @
334 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
335 add r7, r12, r7, lsr #8 @
336 @
337 add r12, r14, #0x100 @
338 @
339 add r0, r0, r12 @ b = r0 + delta
340 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
341 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
342 @
343 orr r12, r0, r11, asr #1 @ check if clamping is needed...
344 orr r12, r12, r7 @ ...at all
345 movs r12, r12, asr #15 @
346 beq 15f @ no clamp @
347 movs r12, r0, asr #15 @ clamp b
348 mvnne r0, r12, lsr #15 @
349 andne r0, r0, #0x7c00 @ mask b only if clamped
350 movs r12, r11, asr #16 @ clamp r
351 mvnne r11, r12, lsr #16 @
352 movs r12, r7, asr #15 @ clamp g
353 mvnne r7, r12, lsr #15 @
35415: @ no clamp @
355 @
356 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
357 @
358
359 and r11, r11, #0xf800 @ pack pixel
360 mov r11, r11, lsr #8
361 and r7, r7, #0x7e00
362 orr r11, r11, r7, lsr #12
363 mov r7, r7, lsr#4
364 orr r0, r7, r0, lsr #10
3651: @ busy @
366 ldr r7, [r3] @ r7 = LCD1_BASE
367 tst r7, #LCD1_BUSY_MASK @ bridge busy?
368 bne 1b @
369 str r11, [r3, #0x10] @ send MSB
3701: @ busy @
371 ldr r7, [r3] @ r7 = LCD1_BASE
372 tst r7, #LCD1_BUSY_MASK @ bridge busy?
373 bne 1b @
374 str r0, [r3, #0x10] @ send LSB
375 @
376 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
377 add r12, r7, r7, asl #2 @
378 add r12, r12, r12, asl #4 @
379 add r7, r12, r7, asl #6 @
380 @ compute R, G, and B
381 add r0, r8, r7 @ r0 = b' = Y + bu
382 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
383 rsb r7, r10, r7 @ r7 = g' = Y + guv
384 @
385 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
386 add r0, r12, r0, lsr #8 @
387 @
388 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
389 add r11, r12, r11, lsr #8 @
390 @
391 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
392 add r7, r12, r7, lsr #8 @
393 @
394 add r12, r14, #0x200 @
395 @
396 add r0, r0, r12 @ b = r0 + delta
397 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
398 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
399 @
400 orr r12, r0, r11, asr #1 @ check if clamping is needed...
401 orr r12, r12, r7 @ ...at all
402 movs r12, r12, asr #15 @
403 beq 15f @ no clamp @
404 movs r12, r0, asr #15 @ clamp b
405 mvnne r0, r12, lsr #15 @
406 andne r0, r0, #0x7c00 @ mask b only if clamped
407 movs r12, r11, asr #16 @ clamp r
408 mvnne r11, r12, lsr #16 @
409 movs r12, r7, asr #15 @ clamp g
410 mvnne r7, r12, lsr #15 @
41115: @ no clamp @
412 @
413 ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
414
415 and r11, r11, #0xf800 @ pack pixel
416 mov r11, r11, lsr #8
417 and r7, r7, #0x7e00
418 orr r11, r11, r7, lsr #12
419 mov r7, r7, lsr#4
420 orr r0, r7, r0, lsr #10
4211: @ busy @
422 ldr r7, [r3] @ r7 = LCD1_BASE
423 tst r7, #LCD1_BUSY_MASK @ bridge busy?
424 bne 1b @
425 str r11, [r3, #0x10] @ send MSB
4261: @ busy @
427 ldr r7, [r3] @ r7 = LCD1_BASE
428 tst r7, #LCD1_BUSY_MASK @ bridge busy?
429 bne 1b @
430 str r0, [r3, #0x10] @ send LSB
431
432 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
433 add r12, r7, r7, asl #2 @
434 add r12, r12, r12, asl #4 @
435 add r7, r12, r7, asl #6 @
436 @ compute R, G, and B
437 add r0, r8, r7 @ r0 = b' = Y + bu
438 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
439 rsb r7, r10, r7 @ r7 = g' = Y + guv
440 @
441 @ r8 = bu, r9 = rv, r10 = guv
442 @
443 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
444 add r0, r12, r0, lsr #8 @
445 @
446 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
447 add r11, r12, r11, lsr #8 @
448 @
449 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
450 add r7, r12, r7, lsr #8 @
451 @
452 add r12, r14, #0x300 @
453 @
454 add r0, r0, r12 @ b = r0 + delta
455 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
456 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
457 @
458 orr r12, r0, r11, asr #1 @ check if clamping is needed...
459 orr r12, r12, r7 @ ...at all
460 movs r12, r12, asr #15 @
461 beq 15f @ no clamp @
462 movs r12, r0, asr #15 @ clamp b
463 mvnne r0, r12, lsr #15 @
464 andne r0, r0, #0x7c00 @ mask b only if clamped
465 movs r12, r11, asr #16 @ clamp r
466 mvnne r11, r12, lsr #16 @
467 movs r12, r7, asr #15 @ clamp g
468 mvnne r7, r12, lsr #15 @
46915: @ no clamp @
470 @
471 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
472
473 and r11, r11, #0xf800 @ pack pixel
474 mov r11, r11, lsr #8
475 and r7, r7, #0x7e00
476 orr r11, r11, r7, lsr #12
477 mov r7, r7, lsr#4
478 orr r0, r7, r0, lsr #10
4791: @ busy @
480 ldr r7, [r3] @ r7 = LCD1_BASE
481 tst r7, #LCD1_BUSY_MASK @ bridge busy?
482 bne 1b @
483 str r11, [r3, #0x10] @ send MSB
4841: @ busy @
485 ldr r7, [r3] @ r7 = LCD1_BASE
486 tst r7, #LCD1_BUSY_MASK @ bridge busy?
487 bne 1b @
488 str r0, [r3, #0x10] @ send LSB
489
490 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
491 add r12, r7, r7, asl #2 @
492 add r12, r12, r12, asl #4 @
493 add r7, r12, r7, asl #6 @
494 @ compute R, G, and B
495 add r0, r8, r7 @ r0 = b' = Y + bu
496 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
497 rsb r7, r10, r7 @ r7 = g' = Y + guv
498 @
499 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
500 add r0, r12, r0, lsr #8 @
501 @
502 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
503 add r11, r12, r11, lsr #8 @
504 @
505 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
506 add r7, r12, r7, lsr #8 @
507 @
508 @ This element is zero - use r14 @
509 @
510 add r0, r0, r14 @ b = r0 + delta
511 add r11, r11, r14, lsl #1 @ r = r11 + delta*2
512 add r7, r7, r14, lsr #1 @ g = r7 + delta/2
513 @
514 orr r12, r0, r11, asr #1 @ check if clamping is needed...
515 orr r12, r12, r7 @ ...at all
516 movs r12, r12, asr #15 @
517 beq 15f @ no clamp @
518 movs r12, r0, asr #15 @ clamp b
519 mvnne r0, r12, lsr #15 @
520 andne r0, r0, #0x7c00 @ mask b only if clamped
521 movs r12, r11, asr #16 @ clamp r
522 mvnne r11, r12, lsr #16 @
523 movs r12, r7, asr #15 @ clamp g
524 mvnne r7, r12, lsr #15 @
52515: @ no clamp @
526
527 and r11, r11, #0xf800 @ pack pixel
528 mov r11, r11, lsr #8
529 and r7, r7, #0x7e00
530 orr r11, r11, r7, lsr #12
531 mov r7, r7, lsr#4
532 orr r0, r7, r0, lsr #10
5331: @ busy @
534 ldr r7, [r3] @ r7 = LCD1_BASE
535 tst r7, #LCD1_BUSY_MASK @ bridge busy?
536 bne 1b @
537 str r11, [r3, #0x10] @ send MSB
5381: @ busy @
539 ldr r7, [r3] @ r7 = LCD1_BASE
540 tst r7, #LCD1_BUSY_MASK @ bridge busy?
541 bne 1b @
542 str r0, [r3, #0x10] @ send LSB
543
544 subs r1, r1, #2 @ subtract block from width
545 bgt 10b @ loop line @
546 @
547 ldmfd sp!, { r4-r12, pc } @ restore registers and return
548 .ltorg @ dump constant pool
549 .size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither