mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 13:12:37 -05:00
Remove YUV blitting functions and LCD modes
None of this is needed now that mpegplayer is gone. Change-Id: I360366db8513e4d988021e8d7b7d8eb09930efb8
This commit is contained in:
parent
b371ff1f47
commit
fe6aa21e9e
54 changed files with 3 additions and 9638 deletions
|
|
@ -1,550 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
* Heavily based on lcd-as-memframe.c by Michael Sevakis
|
||||
* Adapted for Sansa Fuze/e200v2 by Rafaël Carré
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#define DBOP_BUSY (1<<10)
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Scaled, normalized, rounded and tweaked to yield RGB 565:
|
||||
* |R| |74 0 101| |Y' - 16| >> 9
|
||||
* |G| = |74 -24 -51| |Cb - 128| >> 8
|
||||
* |B| |74 128 0| |Cr - 128| >> 9
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines
|
||||
.type lcd_write_yuv420_lines, %function
|
||||
lcd_write_yuv420_lines:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
stmfd sp!, { r4-r11, lr } @ save non-scratch
|
||||
|
||||
mov r3, #0xC8000000 @
|
||||
orr r3, r3, #0x120000 @ r3 = DBOP_BASE
|
||||
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@ r0 = scratch
|
||||
ldr r12, [r3, #8] @
|
||||
sub r2, r2, #1 @ stride -= 1
|
||||
orr r12, r12, #3<<13 @ DBOP_CTRL |= (1<<13|1<<14) (32bit mode)
|
||||
#ifdef SANSA_FUZEV2
|
||||
bic r12, r12, #1<<13 @ DBOP_CTRL &= ~(1<<13),still 32bit mode
|
||||
#endif
|
||||
str r12, [r3, #8] @
|
||||
10: @ loop line @
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
|
||||
add r7, r12, r7, asl #5 @ by one less when adding - same for all
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
|
||||
add r10, r10, r10, asl #4 @
|
||||
add r10, r10, r8, asl #3 @
|
||||
add r10, r10, r8, asl #4 @
|
||||
@
|
||||
add lr, r9, r9, asl #2 @ r9 = Cr*101
|
||||
add lr, lr, r9, asl #5 @
|
||||
add r9, lr, r9, asl #6 @
|
||||
@
|
||||
add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
|
||||
mov r8, r8, asr #2 @
|
||||
add r9, r9, #256 @ r9 = rv = (r9 + 256) >> 9
|
||||
mov r9, r9, asr #9 @
|
||||
rsb r10, r10, #128 @ r10 = guv = (-r10 + 128) >> 8
|
||||
mov r10, r10, asr #8 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
|
||||
add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r0, lr @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r0, #31 @ clamp b
|
||||
mvnhi r0, r0, asr #31 @
|
||||
andhi r0, r0, #31 @
|
||||
cmp lr, #31 @ clamp r
|
||||
mvnhi lr, lr, asr #31 @
|
||||
andhi lr, lr, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
|
||||
orr r11, r0, r7, lsl #5 @ r11 = (r << 11) | (g << 5) | b
|
||||
orr r11, r0, r7, lsl #5 @ r11 = (r << 11) | (g << 5) | b
|
||||
#ifdef SANSA_FUZEV2
|
||||
mov r0, r11, lsr #8 @
|
||||
bic r11, r11, #0xff00 @
|
||||
orr r11, r0, r11, lsl #8 @ swap bytes
|
||||
#endif
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
|
||||
add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r0, lr @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r0, #31 @ clamp b
|
||||
mvnhi r0, r0, asr #31 @
|
||||
andhi r0, r0, #31 @
|
||||
cmp lr, #31 @ clamp r
|
||||
mvnhi lr, lr, asr #31 @
|
||||
andhi lr, lr, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
@
|
||||
orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
|
||||
orr r0, r0, r7, lsl #5 @ r0 = (r << 11) | (g << 5) | b
|
||||
|
||||
#ifdef SANSA_FUZEV2
|
||||
mov r7, r0, lsr #8 @
|
||||
bic r7, r7, #0xff00 @
|
||||
orr r0, r7, r0, lsl #8 @ swap bytes
|
||||
#endif
|
||||
|
||||
orr r0, r11, r0, lsl#16 @ pack with 2nd pixel
|
||||
str r0, [r3, #0x10] @ write pixel
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
|
||||
add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r0, lr @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r0, #31 @ clamp b
|
||||
mvnhi r0, r0, asr #31 @
|
||||
andhi r0, r0, #31 @
|
||||
cmp lr, #31 @ clamp r
|
||||
mvnhi lr, lr, asr #31 @
|
||||
andhi lr, lr, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
@
|
||||
orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
|
||||
orr r11, r0, r7, lsl #5 @ r0 = (r << 11) | (g << 5) | b
|
||||
|
||||
#ifdef SANSA_FUZEV2
|
||||
mov r0, r11, lsr #8 @
|
||||
bic r11, r11, #0xff00 @
|
||||
orr r11, r0, r11, lsl #8 @ swap byte
|
||||
#endif
|
||||
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
|
||||
add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r0, lr @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r0, #31 @ clamp b
|
||||
mvnhi r0, r0, asr #31 @
|
||||
andhi r0, r0, #31 @
|
||||
cmp lr, #31 @ clamp r
|
||||
mvnhi lr, lr, asr #31 @
|
||||
andhi lr, lr, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
|
||||
orr r0, r0, r7, lsl #5 @ r0 = (r << 11) | (g << 5) | b
|
||||
|
||||
#ifdef SANSA_FUZEV2
|
||||
mov r7, r0, lsr #8 @
|
||||
bic r7, r7, #0xff00 @
|
||||
orr r0, r7, r0, lsl #8 @ swap bytes
|
||||
#endif
|
||||
|
||||
orr r0, r11, r0, lsl#16 @ pack with 2nd pixel
|
||||
str r0, [r3, #0x10] @ write pixel
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
1: @ busy
|
||||
@ writing at max 110*32 (LCD_WIDTH/2), the fifo is bigger
|
||||
@ so polling fifo empty only after each line is save
|
||||
ldr r7, [r3,#0xc] @ r7 = DBOP_STATUS
|
||||
tst r7, #DBOP_BUSY @ fifo not empty?
|
||||
beq 1b @
|
||||
|
||||
ldmpc regs=r4-r11 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride,
|
||||
* int x_screen,
|
||||
* int y_screen);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Red scaled at twice g & b but at same precision to place it in correct
|
||||
* bit position after multiply and leave instruction count lower.
|
||||
* |R| |258 0 408| |Y' - 16|
|
||||
* |G| = |149 -49 -104| |Cb - 128|
|
||||
* |B| |149 258 0| |Cr - 128|
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*
|
||||
* Kernel pattern (raw|rotated|use order):
|
||||
* 5 3 4 2 2 6 3 7 row0 row2 > down
|
||||
* 1 7 0 6 | 4 0 5 1 | 2 4 6 0 3 5 7 1 col0 left
|
||||
* 4 2 5 3 | 3 7 2 6 | 3 5 7 1 2 4 6 0 col2 \/
|
||||
* 0 6 1 7 5 1 4 0
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines_odither
|
||||
.type lcd_write_yuv420_lines_odither, %function
|
||||
lcd_write_yuv420_lines_odither:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
@ r3 = x_screen
|
||||
@ [sp] = y_screen
|
||||
stmfd sp!, { r4-r11, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@
|
||||
ldr r14, [sp, #36] @ Line up pattern and kernel quadrant
|
||||
sub r2, r2, #1 @ stride =- 1
|
||||
eor r14, r14, r3 @
|
||||
and r14, r14, #0x2 @
|
||||
mov r14, r14, lsl #6 @ 0x00 or 0x80
|
||||
|
||||
mov r3, #0xC8000000 @
|
||||
orr r3, r3, #0x120000 @ r3 = DBOP_BASE, need to be redone
|
||||
@ due to lack of registers
|
||||
ldr r12, [r3, #8] @
|
||||
orr r12, r12, #3<<13 @ DBOP_CTRL |= (1<<13|1<<14)
|
||||
#ifdef SANSA_FUZEV2
|
||||
bic r12, r12, #1<<13 @ DBOP_CTRL &= ~(1<<13), still 32bit mode
|
||||
#endif
|
||||
str r12, [r3, #8] @ (32bit mode)
|
||||
10: @ loop line @
|
||||
@
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
eor r14, r14, #0x80 @ flip pattern quadrant
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
|
||||
add r10, r10, r8, asl #5 @
|
||||
add r10, r10, r9, asl #3 @
|
||||
add r10, r10, r9, asl #5 @
|
||||
add r10, r10, r9, asl #6 @
|
||||
@
|
||||
mov r8, r8, asl #1 @ r8 = bu = Cb*258
|
||||
add r8, r8, r8, asl #7 @
|
||||
@
|
||||
add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
|
||||
add r9, r9, r9, asl #4 @
|
||||
mov r9, r9, asl #3 @
|
||||
@
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7 @ r0 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
|
||||
add r0, r12, r0, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x100 @
|
||||
@
|
||||
add r0, r0, r12 @ b = r0 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r0, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r0, asr #15 @ clamp b
|
||||
mvnne r0, r12, lsr #15 @
|
||||
andne r0, r0, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r0, lsr #10 @ (b >> 10)
|
||||
#ifdef SANSA_FUZEV2
|
||||
mov r7, r3, lsr #8 @
|
||||
bic r3, r3, #0xff00 @
|
||||
orr r3, r7, r3, lsl #8 @ swap pixel
|
||||
#endif
|
||||
@ save pixel
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7 @ r0 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
|
||||
add r0, r12, r0, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x200 @
|
||||
@
|
||||
add r0, r0, r12 @ b = r0 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r0, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r0, asr #15 @ clamp b
|
||||
mvnne r0, r12, lsr #15 @
|
||||
andne r0, r0, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r0, r11, r0, lsr #10 @ (b >> 10)
|
||||
#ifdef SANSA_FUZEV2
|
||||
mov r7, r0, lsr #8 @
|
||||
bic r0, r0, #0xff00 @
|
||||
orr r0, r7, r0, lsl #8 @ swap pixel
|
||||
#endif
|
||||
orr r3, r3, r0, lsl#16 @ pack with 2nd pixel
|
||||
mov r0, #0xC8000000 @
|
||||
orr r0, r0, #0x120000 @ r3 = DBOP_BASE
|
||||
|
||||
str r3, [r0, #0x10] @ write pixel
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7 @ r0 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
|
||||
add r0, r12, r0, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x300 @
|
||||
@
|
||||
add r0, r0, r12 @ b = r0 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r0, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r0, asr #15 @ clamp b
|
||||
mvnne r0, r12, lsr #15 @
|
||||
andne r0, r0, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r0, lsr #10 @ (b >> 10)
|
||||
#ifdef SANSA_FUZEV2
|
||||
mov r7, r3, lsr #8 @
|
||||
bic r3, r3, #0xff00 @
|
||||
orr r3, r7, r3, lsl #8 @ swap pixel
|
||||
#endif
|
||||
@ save pixel
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7 @ r0 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
|
||||
add r0, r12, r0, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
@ This element is zero - use r14 @
|
||||
@
|
||||
add r0, r0, r14 @ b = r0 + delta
|
||||
add r11, r11, r14, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r14, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r0, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r0, asr #15 @ clamp b
|
||||
mvnne r0, r12, lsr #15 @
|
||||
andne r0, r0, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r0, r11, r0, lsr #10 @ (b >> 10)
|
||||
#ifdef SANSA_FUZEV2
|
||||
mov r7, r0, lsr #8 @
|
||||
bic r0, r0, #0xff00 @
|
||||
orr r0, r7, r0, lsl #8 @ swap pixel
|
||||
#endif
|
||||
orr r3, r3, r0, lsl#16 @ pack with 2nd pixel
|
||||
mov r0, #0xC8000000 @
|
||||
orr r0, r0, #0x120000 @ r3 = DBOP_BASE
|
||||
|
||||
str r3, [r0, #0x10] @ write pixel
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
1: @ busy @
|
||||
@ writing at max 110*32 (LCD_WIDTH/2), the fifo is bigger (128*32)
|
||||
@ so polling fifo empty only after each line is save
|
||||
ldr r7, [r0,#0xc] @ r7 = DBOP_STATUS
|
||||
tst r7, #DBOP_BUSY @ fifo not empty?
|
||||
beq 1b @
|
||||
|
||||
ldmpc regs=r4-r11 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
|
||||
|
|
@ -197,86 +197,6 @@ static void lcd_window_y(int ymin, int ymax)
|
|||
lcd_write_reg(R_RAM_ADDR_SET, ymin);
|
||||
}
|
||||
|
||||
static unsigned lcd_yuv_options = 0;
|
||||
|
||||
void lcd_yuv_set_options(unsigned options)
|
||||
{
|
||||
lcd_yuv_options = options;
|
||||
}
|
||||
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
|
||||
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride);
|
||||
extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride,
|
||||
int x_screen, /* To align dither pattern */
|
||||
int y_screen);
|
||||
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD
|
||||
* src_x, src_y, width and height should be even
|
||||
* x, y, width and height have to be within LCD bounds
|
||||
*/
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
unsigned char const * yuv_src[3];
|
||||
off_t z;
|
||||
|
||||
/* Sorry, but width and height must be >= 2 or else */
|
||||
width &= ~1;
|
||||
height >>= 1;
|
||||
|
||||
z = stride*src_y;
|
||||
yuv_src[0] = src[0] + z + src_x;
|
||||
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
|
||||
lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VIDEO);
|
||||
|
||||
lcd_window_x(x, x + width - 1);
|
||||
|
||||
if (lcd_yuv_options & LCD_YUV_DITHER)
|
||||
{
|
||||
do
|
||||
{
|
||||
lcd_window_y(y, y + 1);
|
||||
|
||||
lcd_write_cmd(R_WRITE_DATA_2_GRAM);
|
||||
|
||||
lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y);
|
||||
yuv_src[0] += stride << 1; /* Skip down two luma lines */
|
||||
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
|
||||
yuv_src[2] += stride >> 1;
|
||||
y += 2;
|
||||
}
|
||||
while (--height > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
lcd_window_y(y, y + 1);
|
||||
|
||||
lcd_write_cmd(R_WRITE_DATA_2_GRAM);
|
||||
|
||||
lcd_write_yuv420_lines(yuv_src, width, stride);
|
||||
yuv_src[0] += stride << 1; /* Skip down two luma lines */
|
||||
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
|
||||
yuv_src[2] += stride >> 1;
|
||||
y += 2;
|
||||
}
|
||||
while (--height > 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Update the display.
|
||||
This must be called after all other LCD functions that change the display. */
|
||||
void lcd_update(void)
|
||||
|
|
|
|||
|
|
@ -336,104 +336,6 @@ bool lcd_active(void)
|
|||
|
||||
/*** update functions ***/
|
||||
|
||||
static unsigned lcd_yuv_options = 0;
|
||||
|
||||
void lcd_yuv_set_options(unsigned options)
|
||||
{
|
||||
lcd_yuv_options = options;
|
||||
}
|
||||
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
static void lcd_window_blit(int xmin, int ymin, int xmax, int ymax)
|
||||
{
|
||||
if (!display_flipped)
|
||||
{
|
||||
lcd_write_reg(R_HORIZ_RAM_ADDR_POS,
|
||||
((LCD_WIDTH-1 - xmin) << 8) | (LCD_WIDTH-1 - xmax));
|
||||
lcd_write_reg(R_VERT_RAM_ADDR_POS, (ymax << 8) | ymin);
|
||||
lcd_write_reg(R_RAM_ADDR_SET,
|
||||
(ymin << 8) | (LCD_WIDTH-1 - xmin));
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (xmax << 8) | xmin);
|
||||
lcd_write_reg(R_VERT_RAM_ADDR_POS, (ymax << 8) | ymin);
|
||||
lcd_write_reg(R_RAM_ADDR_SET, (ymax << 8) | xmin);
|
||||
}
|
||||
}
|
||||
|
||||
/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
|
||||
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride);
|
||||
extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride,
|
||||
int x_screen, /* To align dither pattern */
|
||||
int y_screen);
|
||||
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD
|
||||
* src_x, src_y, width and height should be even
|
||||
* x, y, width and height have to be within LCD bounds
|
||||
*/
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
unsigned char const * yuv_src[3];
|
||||
off_t z;
|
||||
|
||||
/* Sorry, but width and height must be >= 2 or else */
|
||||
width &= ~1;
|
||||
height >>= 1;
|
||||
|
||||
z = stride*src_y;
|
||||
yuv_src[0] = src[0] + z + src_x;
|
||||
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
|
||||
lcd_write_reg(R_ENTRY_MODE,
|
||||
display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL
|
||||
);
|
||||
|
||||
if (lcd_yuv_options & LCD_YUV_DITHER)
|
||||
{
|
||||
do
|
||||
{
|
||||
lcd_window_blit(y, x, y+1, x+width-1);
|
||||
|
||||
lcd_write_cmd(R_WRITE_DATA_2_GRAM);
|
||||
|
||||
lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y);
|
||||
yuv_src[0] += stride << 1; /* Skip down two luma lines */
|
||||
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
|
||||
yuv_src[2] += stride >> 1;
|
||||
y += 2;
|
||||
}
|
||||
while (--height > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
lcd_window_blit(y, x, y+1, x+width-1);
|
||||
|
||||
lcd_write_cmd(R_WRITE_DATA_2_GRAM);
|
||||
|
||||
lcd_write_yuv420_lines(yuv_src, width, stride);
|
||||
yuv_src[0] += stride << 1; /* Skip down two luma lines */
|
||||
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
|
||||
yuv_src[2] += stride >> 1;
|
||||
y += 2;
|
||||
}
|
||||
while (--height > 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Update the display.
|
||||
This must be called after all other LCD functions that change the display. */
|
||||
void lcd_update(void)
|
||||
|
|
|
|||
|
|
@ -1,287 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id:$
|
||||
*
|
||||
* Copyright (C) 2010-2011 by Andree Buschmann
|
||||
*
|
||||
* Generic asm helper function used by YUV blitting.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/****************************************************************************
|
||||
* #define FORCE_FIFO_WAIT
|
||||
*
|
||||
* This is not needed in YUV blitting when the LCD IF is fast enough. In this
|
||||
* case YUV-to-RGB conversion per pixel needs longer than the transfer of a
|
||||
* pixel via the LCD IF.
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* Set FIFO wait for both iPod Color and iPod nano1G until we know for which
|
||||
* devices we can switch this off. */
|
||||
#define FORCE_FIFO_WAIT
|
||||
|
||||
.section .icode, "ax", %progbits
|
||||
|
||||
/****************************************************************************
|
||||
* extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
* const unsigned LCD_BASE,
|
||||
* int width,
|
||||
* int stride);
|
||||
*
|
||||
* Conversion from Motion JPEG and MPEG Y'PbPr to RGB is:
|
||||
* |R| |1.164 0.000 1.596| |Y' - 16|
|
||||
* |G| = |1.164 -0.391 -0.813| |Pb - 128|
|
||||
* |B| |1.164 2.018 0.000| |Pr - 128|
|
||||
*
|
||||
* Scaled, normalized, rounded and tweaked to yield RGB 565:
|
||||
* |R| |74 0 101| |Y' - 16| >> 9
|
||||
* |G| = |74 -24 -51| |Cb - 128| >> 8
|
||||
* |B| |74 128 0| |Cr - 128| >> 9
|
||||
*
|
||||
* Converts two lines from YUV to RGB565 and writes to LCD at once. First loop
|
||||
* loads Cb/Cr, calculates the chroma offset and saves them to buffer. Within
|
||||
* the second loop these chroma offset are reloaded from buffer. Within each
|
||||
* loop two pixels are calculated and written to LCD.
|
||||
*/
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines
|
||||
.type lcd_write_yuv420_lines, %function
|
||||
lcd_write_yuv420_lines:
|
||||
/* r0 = src = yuv_src */
|
||||
/* r1 = dst = LCD_BASE */
|
||||
/* r2 = width */
|
||||
/* r3 = stride */
|
||||
stmfd sp!, { r4-r10, lr } /* save non-scratch */
|
||||
ldmia r0, { r9, r10, r12 } /* r9 = yuv_src[0] = Y'_p */
|
||||
/* r10 = yuv_src[1] = Cb_p */
|
||||
/* r12 = yuv_src[2] = Cr_p */
|
||||
add r3, r9, r3 /* r3 = &ysrc[stride] */
|
||||
add r4, r2, r2, asr #1 /* chroma buffer lenght = width/2 *3 */
|
||||
mov r4, r4, asl #2 /* use words for str/ldm possibility */
|
||||
add r4, r4, #19 /* plus room for 4 additional words, */
|
||||
bic r4, r4, #3 /* rounded up to multiples of 4 byte */
|
||||
sub sp, sp, r4 /* and allocate on stack */
|
||||
stmia sp, {r1-r4} /* LCD_BASE, width, &ysrc[stride], stack_alloc */
|
||||
|
||||
mov r7, r2 /* r7 = loop count */
|
||||
add r8, sp, #16 /* chroma buffer */
|
||||
add lr, r1, #0x100 /* LCD data port = LCD2_BASE + 0x100 */
|
||||
|
||||
/* 1st loop start */
|
||||
10: /* loop start */
|
||||
|
||||
ldrb r0, [r10], #1 /* r0 = *usrc++ = *Cb_p++ */
|
||||
ldrb r1, [r12], #1 /* r1 = *vsrc++ = *Cr_p++ */
|
||||
|
||||
sub r0, r0, #128 /* r0 = Cb-128 */
|
||||
sub r1, r1, #128 /* r1 = Cr-128 */
|
||||
|
||||
add r2, r1, r1, asl #1 /* r2 = Cr*51 + Cb*24 */
|
||||
add r2, r2, r2, asl #4
|
||||
add r2, r2, r0, asl #3
|
||||
add r2, r2, r0, asl #4
|
||||
|
||||
add r4, r1, r1, asl #2 /* r1 = Cr*101 */
|
||||
add r4, r4, r1, asl #5
|
||||
add r1, r4, r1, asl #6
|
||||
|
||||
add r1, r1, #256 /* r1 = rv = (r1 + 256) >> 9 */
|
||||
mov r1, r1, asr #9
|
||||
rsb r2, r2, #128 /* r2 = guv = (-r2 + 128) >> 8 */
|
||||
mov r2, r2, asr #8
|
||||
add r0, r0, #2 /* r0 = bu = (Cb*128 + 256) >> 9 */
|
||||
mov r0, r0, asr #2
|
||||
stmia r8!, {r0-r2} /* store r0, r1 and r2 to chroma buffer */
|
||||
|
||||
/* 1st loop, first pixel */
|
||||
ldrb r5, [r9], #1 /* r5 = *ysrc++ = *Y'_p++ */
|
||||
sub r5, r5, #16 /* r5 = (Y'-16) * 74 */
|
||||
add r3, r5, r5, asl #2
|
||||
add r5, r3, r5, asl #5
|
||||
|
||||
add r6, r1, r5, asr #8 /* r6 = r = (Y >> 9) + rv */
|
||||
add r3, r2, r5, asr #7 /* r3 = g = (Y >> 8) + guv */
|
||||
add r4, r0, r5, asr #8 /* r4 = b = (Y >> 9) + bu */
|
||||
|
||||
orr r5, r6, r4 /* check if clamping is needed... */
|
||||
orr r5, r5, r3, asr #1 /* ...at all */
|
||||
cmp r5, #31
|
||||
bls 15f /* -> no clamp */
|
||||
cmp r6, #31 /* clamp r */
|
||||
mvnhi r6, r6, asr #31
|
||||
andhi r6, r6, #31
|
||||
cmp r3, #63 /* clamp g */
|
||||
mvnhi r3, r3, asr #31
|
||||
andhi r3, r3, #63
|
||||
cmp r4, #31 /* clamp b */
|
||||
mvnhi r4, r4, asr #31
|
||||
andhi r4, r4, #31
|
||||
15: /* no clamp */
|
||||
|
||||
/* calculate pixel_1 and save to r4 for later pixel packing */
|
||||
orr r4, r4, r3, lsl #5 /* pixel_1 = r<<11 | g<<5 | b */
|
||||
orr r4, r4, r6, lsl #11 /* r4 = pixel_1 */
|
||||
|
||||
/* 1st loop, second pixel */
|
||||
ldrb r5, [r9], #1 /* r5 = *ysrc++ = *Y'_p++ */
|
||||
sub r5, r5, #16 /* r5 = (Y'-16) * 74 */
|
||||
add r3, r5, r5, asl #2
|
||||
add r5, r3, r5, asl #5
|
||||
|
||||
add r6, r1, r5, asr #8 /* r6 = r = (Y >> 9) + rv */
|
||||
add r3, r2, r5, asr #7 /* r3 = g = (Y >> 8) + guv */
|
||||
add r5, r0, r5, asr #8 /* r5 = b = (Y >> 9) + bu */
|
||||
|
||||
orr r0, r6, r5 /* check if clamping is needed... */
|
||||
orr r0, r0, r3, asr #1 /* ...at all */
|
||||
cmp r0, #31
|
||||
bls 15f /* -> no clamp */
|
||||
cmp r6, #31 /* clamp r */
|
||||
mvnhi r6, r6, asr #31
|
||||
andhi r6, r6, #31
|
||||
cmp r3, #63 /* clamp g */
|
||||
mvnhi r3, r3, asr #31
|
||||
andhi r3, r3, #63
|
||||
cmp r5, #31 /* clamp b */
|
||||
mvnhi r5, r5, asr #31
|
||||
andhi r5, r5, #31
|
||||
15: /* no clamp */
|
||||
|
||||
/* calculate pixel_2 and pack with pixel_1 before writing */
|
||||
orr r5, r5, r3, lsl #5 /* pixel_2 = r<<11 | g<<5 | b */
|
||||
orr r5, r5, r6, lsl #11 /* r5 = pixel_2 */
|
||||
#ifdef FORCE_FIFO_WAIT
|
||||
/* wait for FIFO half full */
|
||||
.fifo_wait1:
|
||||
ldr r3, [lr, #-0xE0] /* while !(LCD2_BLOCK_CTRL & 0x1000000); */
|
||||
tst r3, #0x1000000
|
||||
beq .fifo_wait1
|
||||
#endif
|
||||
|
||||
mov r3, r4, lsl #8 /* swap pixel_1 */
|
||||
and r3, r3, #0xff00
|
||||
add r4, r3, r4, lsr #8
|
||||
|
||||
orr r4, r4, r5, lsl #24 /* swap pixel_2 and pack with pixel_1 */
|
||||
mov r5, r5, lsr #8
|
||||
orr r4, r4, r5, lsl #16
|
||||
|
||||
str r4, [lr] /* write pixel_1 and pixel_2 */
|
||||
|
||||
subs r7, r7, #2 /* check for loop end */
|
||||
bgt 10b /* back to beginning */
|
||||
/* 1st loop end */
|
||||
|
||||
/* Reload several registers for pointer rewinding for next loop */
|
||||
add r8, sp, #16 /* chroma buffer */
|
||||
ldmia sp, { r1, r7, r9} /* r1 = LCD_BASE */
|
||||
/* r7 = loop count */
|
||||
/* r9 = &ysrc[stride] */
|
||||
|
||||
/* 2nd loop start */
|
||||
20: /* loop start */
|
||||
/* restore r0 (bu), r1 (rv) and r2 (guv) from chroma buffer */
|
||||
ldmia r8!, {r0-r2}
|
||||
|
||||
/* 2nd loop, first pixel */
|
||||
ldrb r5, [r9], #1 /* r5 = *ysrc++ = *Y'_p++ */
|
||||
sub r5, r5, #16 /* r5 = (Y'-16) * 74 */
|
||||
add r3, r5, r5, asl #2
|
||||
add r5, r3, r5, asl #5
|
||||
|
||||
add r6, r1, r5, asr #8 /* r6 = r = (Y >> 9) + rv */
|
||||
add r3, r2, r5, asr #7 /* r3 = g = (Y >> 8) + guv */
|
||||
add r4, r0, r5, asr #8 /* r4 = b = (Y >> 9) + bu */
|
||||
|
||||
orr r5, r6, r4 /* check if clamping is needed... */
|
||||
orr r5, r5, r3, asr #1 /* ...at all */
|
||||
cmp r5, #31
|
||||
bls 15f /* -> no clamp */
|
||||
cmp r6, #31 /* clamp r */
|
||||
mvnhi r6, r6, asr #31
|
||||
andhi r6, r6, #31
|
||||
cmp r3, #63 /* clamp g */
|
||||
mvnhi r3, r3, asr #31
|
||||
andhi r3, r3, #63
|
||||
cmp r4, #31 /* clamp b */
|
||||
mvnhi r4, r4, asr #31
|
||||
andhi r4, r4, #31
|
||||
15: /* no clamp */
|
||||
/* calculate pixel_1 and save to r4 for later pixel packing */
|
||||
orr r4, r4, r3, lsl #5 /* pixel_1 = r<<11 | g<<5 | b */
|
||||
orr r4, r4, r6, lsl #11 /* r4 = pixel_1 */
|
||||
|
||||
/* 2nd loop, second pixel */
|
||||
ldrb r5, [r9], #1 /* r5 = *ysrc++ = *Y'_p++ */
|
||||
sub r5, r5, #16 /* r5 = (Y'-16) * 74 */
|
||||
add r3, r5, r5, asl #2
|
||||
add r5, r3, r5, asl #5
|
||||
|
||||
add r6, r1, r5, asr #8 /* r6 = r = (Y >> 9) + rv */
|
||||
add r3, r2, r5, asr #7 /* r3 = g = (Y >> 8) + guv */
|
||||
add r5, r0, r5, asr #8 /* r5 = b = (Y >> 9) + bu */
|
||||
|
||||
orr r0, r6, r5 /* check if clamping is needed... */
|
||||
orr r0, r0, r3, asr #1 /* ...at all */
|
||||
cmp r0, #31
|
||||
bls 15f /* -> no clamp */
|
||||
cmp r6, #31 /* clamp r */
|
||||
mvnhi r6, r6, asr #31
|
||||
andhi r6, r6, #31
|
||||
cmp r3, #63 /* clamp g */
|
||||
mvnhi r3, r3, asr #31
|
||||
andhi r3, r3, #63
|
||||
cmp r5, #31 /* clamp b */
|
||||
mvnhi r5, r5, asr #31
|
||||
andhi r5, r5, #31
|
||||
15: /* no clamp */
|
||||
|
||||
/* calculate pixel_2 and pack with pixel_1 before writing */
|
||||
orr r5, r5, r3, lsl #5 /* pixel_2 = r<<11 | g<<5 | b */
|
||||
orr r5, r5, r6, lsl #11 /* r5 = pixel_2 */
|
||||
#ifdef FORCE_FIFO_WAIT
|
||||
/* wait for FIFO half full */
|
||||
.fifo_wait2:
|
||||
ldr r3, [lr, #-0xE0] /* while !(LCD2_BLOCK_CTRL & 0x1000000); */
|
||||
tst r3, #0x1000000
|
||||
beq .fifo_wait2
|
||||
#endif
|
||||
|
||||
mov r3, r4, lsl #8 /* swap pixel_1 */
|
||||
and r3, r3, #0xff00
|
||||
add r4, r3, r4, lsr #8
|
||||
|
||||
orr r4, r4, r5, lsl #24 /* swap pixel_2 and pack with pixel_1 */
|
||||
mov r5, r5, lsr #8
|
||||
orr r4, r4, r5, lsl #16
|
||||
|
||||
str r4, [lr] /* write pixel_1 and pixel_2 */
|
||||
|
||||
subs r7, r7, #2 /* check for loop end */
|
||||
bgt 20b /* back to beginning */
|
||||
/* 2nd loop end */
|
||||
|
||||
ldr r3, [sp, #12]
|
||||
add sp, sp, r3 /* deallocate buffer */
|
||||
ldmpc regs=r4-r10 /* restore registers */
|
||||
|
||||
.ltorg
|
||||
.size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
|
||||
|
|
@ -202,62 +202,6 @@ static void lcd_setup_drawing_region(int x, int y, int width, int height)
|
|||
}
|
||||
}
|
||||
|
||||
/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */
|
||||
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
const unsigned int lcd_baseadress,
|
||||
int width,
|
||||
int stride);
|
||||
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
int z;
|
||||
unsigned char const * yuv_src[3];
|
||||
|
||||
width = (width + 1) & ~1; /* ensure width is even */
|
||||
height = (height + 1) & ~1; /* ensure height is even */
|
||||
|
||||
lcd_setup_drawing_region(x, y, width, height);
|
||||
|
||||
z = stride * src_y;
|
||||
yuv_src[0] = src[0] + z + src_x;
|
||||
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
|
||||
while (height > 0) {
|
||||
int r, h, pixels_to_write;
|
||||
|
||||
pixels_to_write = (width * height) * 2;
|
||||
h = height;
|
||||
|
||||
/* calculate how much we can do in one go */
|
||||
if (pixels_to_write > 0x10000) {
|
||||
h = ((0x10000/2) / width) & ~1; /* ensure h is even */
|
||||
pixels_to_write = (width * h) * 2;
|
||||
}
|
||||
|
||||
LCD2_BLOCK_CTRL = 0x10000080;
|
||||
LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
|
||||
LCD2_BLOCK_CTRL = 0x34000000;
|
||||
|
||||
r = h>>1; /* lcd_write_yuv420_lines writes two lines at once */
|
||||
do {
|
||||
lcd_write_yuv420_lines(yuv_src, LCD2_BASE, width, stride);
|
||||
yuv_src[0] += stride << 1;
|
||||
yuv_src[1] += stride >> 1;
|
||||
yuv_src[2] += stride >> 1;
|
||||
} while (--r > 0);
|
||||
|
||||
/* transfer of pixels_to_write bytes finished */
|
||||
while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
|
||||
LCD2_BLOCK_CONFIG = 0;
|
||||
|
||||
height -= h;
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper function writes 'count' consecutive pixels from src to LCD IF */
|
||||
static void lcd_write_line(int count, unsigned long *src)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -63,240 +63,3 @@ lcd_write_data: /* r1 = pixel count, must be even */
|
|||
strne r3, [lr]
|
||||
|
||||
ldmpc regs=r4
|
||||
|
||||
/****************************************************************************
|
||||
* extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
* unsigned bcmaddr
|
||||
* int width,
|
||||
* int stride);
|
||||
*
|
||||
* Conversion from Motion JPEG and MPEG Y'PbPr to RGB is:
|
||||
* |R| |1.164 0.000 1.596| |Y' - 16|
|
||||
* |G| = |1.164 -0.391 -0.813| |Pb - 128|
|
||||
* |B| |1.164 2.018 0.000| |Pr - 128|
|
||||
*
|
||||
* Scaled, normalized, rounded and tweaked to yield RGB 565:
|
||||
* |R| |74 0 101| |Y' - 16| >> 9
|
||||
* |G| = |74 -24 -51| |Cb - 128| >> 8
|
||||
* |B| |74 128 0| |Cr - 128| >> 9
|
||||
*
|
||||
* Converts two lines from YUV to RGB565 and writes to BCM at once. First loop
|
||||
* loads Cb/Cr, calculates the chroma offset and saves them to buffer. Within
|
||||
* the second loop these chroma offset are reloaded from buffer.
|
||||
* Within each loop two pixels are calculated and written to BCM. Before each
|
||||
* loop the desired destination address is transmitted to BCM.
|
||||
*/
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines
|
||||
.type lcd_write_yuv420_lines, %function
|
||||
lcd_write_yuv420_lines:
|
||||
/* r0 = src = yuv_src */
|
||||
/* r1 = dst = bcmaddr */
|
||||
/* r2 = width */
|
||||
/* r3 = stride */
|
||||
stmfd sp!, { r4-r10, lr } /* save non-scratch */
|
||||
ldmia r0, { r9, r10, r12 } /* r9 = yuv_src[0] = Y'_p */
|
||||
/* r10 = yuv_src[1] = Cb_p */
|
||||
/* r12 = yuv_src[2] = Cr_p */
|
||||
add r3, r9, r3 /* r3 = &ysrc[stride] */
|
||||
add r4, r2, r2, asr #1 /* chroma buffer lenght = width/2 *3 */
|
||||
mov r4, r4, asl #2 /* use words for str/ldm possibility */
|
||||
add r4, r4, #19 /* plus room for 4 additional words, */
|
||||
bic r4, r4, #3 /* rounded up to multiples of 4 byte */
|
||||
sub sp, sp, r4 /* and allocate on stack */
|
||||
stmia sp, {r1-r4} /* bcmaddr, width, &ysrc[stride], stack_alloc */
|
||||
|
||||
mov r7, r2 /* r7 = loop count */
|
||||
add r8, sp, #16 /* chroma buffer */
|
||||
mov lr, #0x30000000 /* LCD data port */
|
||||
|
||||
/* The following writes dest address to BCM and waits for write ready */
|
||||
orr r2, lr, #0x00010000 /* r2 = BCM_WR_ADDR32 */
|
||||
orr r6, lr, #0x00030000 /* r6 = BCM_CONTROL */
|
||||
str r1, [r2] /* BCM_WR_ADDR32 = bcmaddr */
|
||||
.busy_1:
|
||||
ldrh r1, [r6] /* while (!(BCM_CONTROL & 0x2)) */
|
||||
tst r1, #0x2
|
||||
beq .busy_1
|
||||
|
||||
/* 1st loop start */
|
||||
10: /* loop start */
|
||||
|
||||
ldrb r0, [r10], #1 /* r0 = *usrc++ = *Cb_p++ */
|
||||
ldrb r1, [r12], #1 /* r1 = *vsrc++ = *Cr_p++ */
|
||||
|
||||
sub r0, r0, #128 /* r0 = Cb-128 */
|
||||
sub r1, r1, #128 /* r1 = Cr-128 */
|
||||
|
||||
add r2, r1, r1, asl #1 /* r2 = Cr*51 + Cb*24 */
|
||||
add r2, r2, r2, asl #4
|
||||
add r2, r2, r0, asl #3
|
||||
add r2, r2, r0, asl #4
|
||||
|
||||
add r4, r1, r1, asl #2 /* r1 = Cr*101 */
|
||||
add r4, r4, r1, asl #5
|
||||
add r1, r4, r1, asl #6
|
||||
|
||||
add r1, r1, #256 /* r1 = rv = (r1 + 256) >> 9 */
|
||||
mov r1, r1, asr #9
|
||||
rsb r2, r2, #128 /* r2 = guv = (-r2 + 128) >> 8 */
|
||||
mov r2, r2, asr #8
|
||||
add r0, r0, #2 /* r0 = bu = (Cb*128 + 256) >> 9 */
|
||||
mov r0, r0, asr #2
|
||||
stmia r8!, {r0-r2} /* store r0, r1 and r2 to chroma buffer */
|
||||
|
||||
/* 1st loop, first pixel */
|
||||
ldrb r5, [r9], #1 /* r5 = *ysrc++ = *Y'_p++ */
|
||||
sub r5, r5, #16 /* r5 = (Y'-16) * 74 */
|
||||
add r3, r5, r5, asl #2
|
||||
add r5, r3, r5, asl #5
|
||||
|
||||
add r6, r1, r5, asr #8 /* r6 = r = (Y >> 9) + rv */
|
||||
add r3, r2, r5, asr #7 /* r3 = g = (Y >> 8) + guv */
|
||||
add r4, r0, r5, asr #8 /* r4 = b = (Y >> 9) + bu */
|
||||
|
||||
orr r5, r6, r4 /* check if clamping is needed... */
|
||||
orr r5, r5, r3, asr #1 /* ...at all */
|
||||
cmp r5, #31
|
||||
bls 15f /* -> no clamp */
|
||||
cmp r6, #31 /* clamp r */
|
||||
mvnhi r6, r6, asr #31
|
||||
andhi r6, r6, #31
|
||||
cmp r3, #63 /* clamp g */
|
||||
mvnhi r3, r3, asr #31
|
||||
andhi r3, r3, #63
|
||||
cmp r4, #31 /* clamp b */
|
||||
mvnhi r4, r4, asr #31
|
||||
andhi r4, r4, #31
|
||||
15: /* no clamp */
|
||||
|
||||
/* calculate pixel_1 and save to r5 for later pixel packing */
|
||||
orr r4, r4, r3, lsl #5 /* pixel_1 = r<<11 | g<<5 | b */
|
||||
orr r5, r4, r6, lsl #11 /* r5 = pixel_1 */
|
||||
|
||||
/* 1st loop, second pixel */
|
||||
ldrb r4, [r9], #1 /* r4 = *ysrc++ = *Y'_p++ */
|
||||
sub r4, r4, #16 /* r4 = (Y'-16) * 74 */
|
||||
add r3, r4, r4, asl #2
|
||||
add r4, r3, r4, asl #5
|
||||
|
||||
add r6, r1, r4, asr #8 /* r6 = r = (Y >> 9) + rv */
|
||||
add r3, r2, r4, asr #7 /* r3 = g = (Y >> 8) + guv */
|
||||
add r4, r0, r4, asr #8 /* r4 = b = (Y >> 9) + bu */
|
||||
|
||||
orr r0, r6, r4 /* check if clamping is needed... */
|
||||
orr r0, r0, r3, asr #1 /* ...at all */
|
||||
cmp r0, #31
|
||||
bls 15f /* -> no clamp */
|
||||
cmp r6, #31 /* clamp r */
|
||||
mvnhi r6, r6, asr #31
|
||||
andhi r6, r6, #31
|
||||
cmp r3, #63 /* clamp g */
|
||||
mvnhi r3, r3, asr #31
|
||||
andhi r3, r3, #63
|
||||
cmp r4, #31 /* clamp b */
|
||||
mvnhi r4, r4, asr #31
|
||||
andhi r4, r4, #31
|
||||
15: /* no clamp */
|
||||
|
||||
/* calculate pixel_2 and pack with pixel_1 before writing */
|
||||
orr r4, r4, r3, lsl #5 /* pixel_2 = r<<11 | g<<5 | b */
|
||||
orr r4, r4, r6, lsl #11 /* r4 = pixel_2 */
|
||||
orr r4, r5, r4, lsl #16 /* r4 = pixel_2<<16 | pixel_1 */
|
||||
str r4, [lr] /* write packed pixels */
|
||||
|
||||
subs r7, r7, #2 /* check for loop end */
|
||||
bgt 10b /* back to beginning */
|
||||
/* 1st loop end */
|
||||
|
||||
/* Reload several registers for pointer rewinding for next loop */
|
||||
add r8, sp, #16 /* chroma buffer */
|
||||
ldmia sp, { r1, r7, r9} /* r1 = bcmaddr */
|
||||
/* r7 = loop count */
|
||||
/* r9 = &ysrc[stride] */
|
||||
|
||||
/* The following writes dest address to BCM and waits for write ready */
|
||||
orr r2, lr, #0x00010000 /* r2 = BCM_WR_ADDR32 */
|
||||
orr r6, lr, #0x00030000 /* r6 = BCM_CONTROL */
|
||||
add r1, r1, #640 /* dst += (LCD_WIDTH*2) */
|
||||
str r1, [r2] /* BCM_WR_ADDR32 = dst */
|
||||
.busy_2:
|
||||
ldrh r1, [r6] /* while (!(BCM_CONTROL & 0x2)) */
|
||||
tst r1, #0x2
|
||||
beq .busy_2
|
||||
|
||||
|
||||
/* 2nd loop start */
|
||||
20: /* loop start */
|
||||
/* restore r0 (bu), r1 (rv) and r2 (guv) from chroma buffer */
|
||||
ldmia r8!, {r0-r2}
|
||||
|
||||
/* 2nd loop, first pixel */
|
||||
ldrb r5, [r9], #1 /* r5 = *ysrc++ = *Y'_p++ */
|
||||
sub r5, r5, #16 /* r5 = (Y'-16) * 74 */
|
||||
add r3, r5, r5, asl #2
|
||||
add r5, r3, r5, asl #5
|
||||
|
||||
add r6, r1, r5, asr #8 /* r6 = r = (Y >> 9) + rv */
|
||||
add r3, r2, r5, asr #7 /* r3 = g = (Y >> 8) + guv */
|
||||
add r4, r0, r5, asr #8 /* r4 = b = (Y >> 9) + bu */
|
||||
|
||||
orr r5, r6, r4 /* check if clamping is needed... */
|
||||
orr r5, r5, r3, asr #1 /* ...at all */
|
||||
cmp r5, #31
|
||||
bls 15f /* -> no clamp */
|
||||
cmp r6, #31 /* clamp r */
|
||||
mvnhi r6, r6, asr #31
|
||||
andhi r6, r6, #31
|
||||
cmp r3, #63 /* clamp g */
|
||||
mvnhi r3, r3, asr #31
|
||||
andhi r3, r3, #63
|
||||
cmp r4, #31 /* clamp b */
|
||||
mvnhi r4, r4, asr #31
|
||||
andhi r4, r4, #31
|
||||
15: /* no clamp */
|
||||
/* calculate pixel_1 and save to r5 for later pixel packing */
|
||||
orr r4, r4, r3, lsl #5 /* pixel_1 = r<<11 | g<<5 | b */
|
||||
orr r5, r4, r6, lsl #11 /* r5 = pixel_1 */
|
||||
|
||||
/* 2nd loop, second pixel */
|
||||
ldrb r4, [r9], #1 /* r4 = *ysrc++ = *Y'_p++ */
|
||||
sub r4, r4, #16 /* r4 = (Y'-16) * 74 */
|
||||
add r3, r4, r4, asl #2
|
||||
add r4, r3, r4, asl #5
|
||||
|
||||
add r6, r1, r4, asr #8 /* r6 = r = (Y >> 9) + rv */
|
||||
add r3, r2, r4, asr #7 /* r3 = g = (Y >> 8) + guv */
|
||||
add r4, r0, r4, asr #8 /* r4 = b = (Y >> 9) + bu */
|
||||
|
||||
orr r0, r6, r4 /* check if clamping is needed... */
|
||||
orr r0, r0, r3, asr #1 /* ...at all */
|
||||
cmp r0, #31
|
||||
bls 15f /* -> no clamp */
|
||||
cmp r6, #31 /* clamp r */
|
||||
mvnhi r6, r6, asr #31
|
||||
andhi r6, r6, #31
|
||||
cmp r3, #63 /* clamp g */
|
||||
mvnhi r3, r3, asr #31
|
||||
andhi r3, r3, #63
|
||||
cmp r4, #31 /* clamp b */
|
||||
mvnhi r4, r4, asr #31
|
||||
andhi r4, r4, #31
|
||||
15: /* no clamp */
|
||||
|
||||
/* calculate pixel_2 and pack with pixel_1 before writing */
|
||||
orr r4, r4, r3, lsl #5 /* pixel_2 = r<<11 | g<<5 | b */
|
||||
orr r4, r4, r6, lsl #11 /* r4 = pixel_2 */
|
||||
orr r4, r5, r4, lsl #16 /* r4 = pixel_2<<16 | pixel_1 */
|
||||
str r4, [lr] /* write packed pixels */
|
||||
|
||||
subs r7, r7, #2 /* check for loop end */
|
||||
bgt 20b /* back to beginning */
|
||||
/* 2nd loop end */
|
||||
|
||||
ldr r3, [sp, #12]
|
||||
add sp, sp, r3 /* deallocate buffer */
|
||||
ldmpc regs=r4-r10 /* restore registers */
|
||||
|
||||
.ltorg
|
||||
.size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
|
||||
|
|
|
|||
|
|
@ -439,53 +439,6 @@ void lcd_update(void)
|
|||
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
|
||||
}
|
||||
|
||||
/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */
|
||||
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
unsigned bcmaddr,
|
||||
int width,
|
||||
int stride);
|
||||
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
unsigned bcmaddr;
|
||||
off_t z;
|
||||
unsigned char const * yuv_src[3];
|
||||
|
||||
#ifdef HAVE_LCD_SLEEP
|
||||
if (!lcd_state.display_on)
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* Sorry, but width and height must be >= 2 or else */
|
||||
width &= ~1;
|
||||
|
||||
z = stride * src_y;
|
||||
yuv_src[0] = src[0] + z + src_x;
|
||||
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
|
||||
/* Prevent the tick from triggering BCM updates while we're writing. */
|
||||
lcd_block_tick();
|
||||
|
||||
bcmaddr = BCMA_CMDPARAM + (LCD_WIDTH*2) * y + (x << 1);
|
||||
height >>= 1;
|
||||
|
||||
do
|
||||
{
|
||||
lcd_write_yuv420_lines(yuv_src, bcmaddr, width, stride);
|
||||
bcmaddr += (LCD_WIDTH*4); /* Skip up two lines */
|
||||
yuv_src[0] += stride << 1;
|
||||
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
|
||||
yuv_src[2] += stride >> 1;
|
||||
}
|
||||
while (--height > 0);
|
||||
|
||||
lcd_unblock_and_update();
|
||||
}
|
||||
|
||||
#ifdef HAVE_LCD_SLEEP
|
||||
/* Executes a BCM command immediately and waits for it to complete.
|
||||
Other BCM commands (eg. LCD updates or lcd_tick) must not interfere.
|
||||
|
|
|
|||
|
|
@ -1,538 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007-2008 by Michael Sevakis
|
||||
*
|
||||
* H10 20GB LCD assembly routines
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Scaled, normalized, rounded and tweaked to yield RGB 565:
|
||||
* |R| |74 0 101| |Y' - 16| >> 9
|
||||
* |G| = |74 -24 -51| |Cb - 128| >> 8
|
||||
* |B| |74 128 0| |Cr - 128| >> 9
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines
|
||||
.type lcd_write_yuv420_lines, %function
|
||||
lcd_write_yuv420_lines:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
stmfd sp!, { r4-r11, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@
|
||||
mov r0, #0x7000000c @ r0 = &LCD2_PORT = 0x70008a0c
|
||||
add r0, r0, #0x8a00 @
|
||||
mov r14, #LCD2_DATA_MASK @
|
||||
@
|
||||
sub r2, r2, #1 @ Adjust stride because of increment
|
||||
10: @ loop line @
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
|
||||
add r7, r12, r7, asl #5 @ by one less when adding - same for all
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
|
||||
add r10, r10, r10, asl #4 @
|
||||
add r10, r10, r8, asl #3 @
|
||||
add r10, r10, r8, asl #4 @
|
||||
@
|
||||
add r11, r9, r9, asl #2 @ r9 = Cr*101
|
||||
add r11, r11, r9, asl #5 @
|
||||
add r9, r11, r9, asl #6 @
|
||||
@
|
||||
add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
|
||||
mov r8, r8, asr #2 @
|
||||
add r9, r9, #256 @ r9 = rv = (r8 + 256) >> 9
|
||||
mov r9, r9, asr #9 @
|
||||
rsb r10, r10, #128 @ r10 = guv = (-r9 + 128) >> 8
|
||||
mov r10, r10, asr #8 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
|
||||
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
|
||||
@
|
||||
orr r7, r14, r3, lsr #8 @ store pixel
|
||||
orr r11, r14, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
@
|
||||
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
|
||||
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
|
||||
@
|
||||
orr r7, r14, r3, lsr #8 @ store pixel
|
||||
orr r11, r14, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
orr r3, r3, r7, lsl #5 @ r3 = b | (g << 5)
|
||||
orr r3, r3, r11, lsl #11 @ r3 |= (r << 11)
|
||||
@
|
||||
orr r7, r14, r3, lsr #8 @ store pixel
|
||||
orr r11, r14, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
|
||||
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
|
||||
@
|
||||
orr r7, r14, r3, lsr #8 @ store pixel
|
||||
orr r11, r14, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r11 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride,
|
||||
* int x_screen,
|
||||
* int y_screen);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Red scaled at twice g & b but at same precision to place it in correct
|
||||
* bit position after multiply and leave instruction count lower.
|
||||
* |R| |258 0 408| |Y' - 16|
|
||||
* |G| = |149 -49 -104| |Cb - 128|
|
||||
* |B| |149 258 0| |Cr - 128|
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*
|
||||
* Kernel pattern (raw|use order):
|
||||
* 5 3 4 2 row0 row2 > down
|
||||
* 1 7 0 6 | 5 1 3 7 4 0 2 6 col0 left
|
||||
* 4 2 5 3 | 4 0 2 6 5 1 3 7 col2 \/
|
||||
* 0 6 1 7
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines_odither
|
||||
.type lcd_write_yuv420_lines_odither, %function
|
||||
lcd_write_yuv420_lines_odither:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
@ r3 = x_screen
|
||||
@ [sp] = y_screen
|
||||
stmfd sp!, { r4-r11, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@
|
||||
ldr r0, [sp, #36] @ Line up pattern and kernel quadrant
|
||||
eor r14, r3, r0 @
|
||||
and r14, r14, #0x2 @
|
||||
mov r14, r14, lsl #6 @ 0x00 or 0x80
|
||||
@
|
||||
mov r0, #0x7000000c @ r0 = &LCD2_PORT = 0x70008a0c
|
||||
add r0, r0, #0x8a00 @
|
||||
@
|
||||
sub r2, r2, #1 @ Adjust stride because of increment
|
||||
10: @ loop line @
|
||||
@
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
eor r14, r14, #0x80 @ flip pattern quadrant
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
|
||||
add r10, r10, r8, asl #5 @
|
||||
add r10, r10, r9, asl #3 @
|
||||
add r10, r10, r9, asl #5 @
|
||||
add r10, r10, r9, asl #6 @
|
||||
@
|
||||
mov r8, r8, asl #1 @ r8 = bu = Cb*258
|
||||
add r8, r8, r8, asl #7 @
|
||||
@
|
||||
add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
|
||||
add r9, r9, r9, asl #4 @
|
||||
mov r9, r9, asl #3 @
|
||||
@
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x200 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
mov r11, #LCD2_DATA_MASK @ store pixel
|
||||
orr r7, r11, r3, lsr #8 @
|
||||
orr r11, r11, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
@ This element is zero - use r14 @
|
||||
@
|
||||
add r3, r3, r14 @ b = r3 + delta
|
||||
add r11, r11, r14, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r14, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
mov r11, #LCD2_DATA_MASK @ store pixel
|
||||
orr r7, r11, r3, lsr #8 @
|
||||
orr r11, r11, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x100 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
mov r11, #LCD2_DATA_MASK @ store pixel
|
||||
orr r7, r11, r3, lsr #8 @
|
||||
orr r11, r11, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x300 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
mov r11, #LCD2_DATA_MASK @ store pixel
|
||||
orr r7, r11, r3, lsr #8 @
|
||||
orr r11, r11, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r11 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
|
||||
|
|
@ -36,8 +36,6 @@ static unsigned short disp_control_rev;
|
|||
/* Contrast setting << 8 */
|
||||
static int lcd_contrast;
|
||||
|
||||
static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
|
||||
|
||||
/* Forward declarations */
|
||||
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
|
||||
static void lcd_display_off(void);
|
||||
|
|
@ -398,94 +396,6 @@ bool lcd_active(void)
|
|||
|
||||
/*** update functions ***/
|
||||
|
||||
void lcd_yuv_set_options(unsigned options)
|
||||
{
|
||||
lcd_yuv_options = options;
|
||||
}
|
||||
|
||||
/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
|
||||
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride);
|
||||
extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride,
|
||||
int x_screen, /* To align dither pattern */
|
||||
int y_screen);
|
||||
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
const unsigned char *yuv_src[3];
|
||||
const unsigned char *ysrc_max;
|
||||
int y0;
|
||||
int options;
|
||||
|
||||
if (!display_on)
|
||||
return;
|
||||
|
||||
width &= ~1;
|
||||
height &= ~1;
|
||||
|
||||
/* calculate the drawing region */
|
||||
|
||||
/* The 20GB LCD is actually 128x160 but rotated 90 degrees so the origin
|
||||
* is actually the bottom left and horizontal and vertical are swapped.
|
||||
* Rockbox expects the origin to be the top left so we need to use
|
||||
* 127 - y instead of just y */
|
||||
|
||||
/* max vert << 8 | start vert */
|
||||
lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x);
|
||||
|
||||
y0 = LCD_HEIGHT - 1 - y + y_offset;
|
||||
|
||||
/* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=0, LG2-0=000 */
|
||||
lcd_write_reg(R_ENTRY_MODE, 0x1020);
|
||||
|
||||
yuv_src[0] = src[0] + src_y * stride + src_x;
|
||||
yuv_src[1] = src[1] + (src_y * stride >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
ysrc_max = yuv_src[0] + height * stride;
|
||||
|
||||
options = lcd_yuv_options;
|
||||
|
||||
do
|
||||
{
|
||||
/* max horiz << 8 | start horiz */
|
||||
lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (y0 << 8) | (y0 - 1));
|
||||
|
||||
/* position cursor (set AD0-AD15) */
|
||||
/* start vert << 8 | start horiz */
|
||||
lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | y0);
|
||||
|
||||
/* start drawing */
|
||||
lcd_send_cmd(R_WRITE_DATA_2_GRAM);
|
||||
|
||||
if (options & LCD_YUV_DITHER)
|
||||
{
|
||||
lcd_write_yuv420_lines_odither(yuv_src, width, stride,
|
||||
x, y);
|
||||
y -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd_write_yuv420_lines(yuv_src, width, stride);
|
||||
}
|
||||
|
||||
y0 -= 2;
|
||||
yuv_src[0] += stride << 1;
|
||||
yuv_src[1] += stride >> 1;
|
||||
yuv_src[2] += stride >> 1;
|
||||
}
|
||||
while (yuv_src[0] < ysrc_max);
|
||||
|
||||
/* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=1, LG2-0=000 */
|
||||
lcd_write_reg(R_ENTRY_MODE, 0x1028);
|
||||
}
|
||||
|
||||
|
||||
/* Update a fraction of the display. */
|
||||
void lcd_update_rect(int x0, int y0, int width, int height)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -118,168 +118,6 @@ void lcd_init_device(void)
|
|||
|
||||
/*** update functions ***/
|
||||
|
||||
#define CSUB_X 2
|
||||
#define CSUB_Y 2
|
||||
|
||||
#define RYFAC (31*257)
|
||||
#define GYFAC (31*257)
|
||||
#define BYFAC (31*257)
|
||||
#define RVFAC 11170 /* 31 * 257 * 1.402 */
|
||||
#define GVFAC (-5690) /* 31 * 257 * -0.714136 */
|
||||
#define GUFAC (-2742) /* 31 * 257 * -0.344136 */
|
||||
#define BUFAC 14118 /* 31 * 257 * 1.772 */
|
||||
|
||||
#define ROUNDOFFS (127*257)
|
||||
#define ROUNDOFFSG (63*257)
|
||||
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
int y0, x0, y1, x1;
|
||||
int ymax;
|
||||
|
||||
width = (width + 1) & ~1;
|
||||
|
||||
/* calculate the drawing region */
|
||||
x0 = x;
|
||||
x1 = x + width - 1;
|
||||
y0 = y;
|
||||
y1 = y + height - 1;
|
||||
|
||||
/* max horiz << 8 | start horiz */
|
||||
lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (x1 << 8) | x0);
|
||||
|
||||
/* max vert << 8 | start vert */
|
||||
lcd_write_reg(R_VERT_RAM_ADDR_POS, (y1 << 8) | y0);
|
||||
|
||||
/* start vert << 8 | start horiz */
|
||||
lcd_write_reg(R_RAM_ADDR_SET, (y0 << 8) | x0);
|
||||
|
||||
/* start drawing */
|
||||
lcd_send_cmd(R_WRITE_DATA_2_GRAM);
|
||||
|
||||
ymax = y + height - 1 ;
|
||||
|
||||
const int stride_div_csub_x = stride/CSUB_X;
|
||||
|
||||
for (; y <= ymax ; y++)
|
||||
{
|
||||
/* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
|
||||
const unsigned char *ysrc = src[0] + stride * src_y + src_x;
|
||||
|
||||
const int uvoffset = stride_div_csub_x * (src_y/CSUB_Y) +
|
||||
(src_x/CSUB_X);
|
||||
|
||||
const unsigned char *usrc = src[1] + uvoffset;
|
||||
const unsigned char *vsrc = src[2] + uvoffset;
|
||||
const unsigned char *row_end = ysrc + width;
|
||||
|
||||
int y, u, v;
|
||||
int red1, green1, blue1;
|
||||
int red2, green2, blue2;
|
||||
unsigned rbits, gbits, bbits;
|
||||
|
||||
int rc, gc, bc;
|
||||
|
||||
do
|
||||
{
|
||||
u = *usrc++ - 128;
|
||||
v = *vsrc++ - 128;
|
||||
rc = RVFAC * v + ROUNDOFFS;
|
||||
gc = GVFAC * v + GUFAC * u + ROUNDOFFSG;
|
||||
bc = BUFAC * u + ROUNDOFFS;
|
||||
|
||||
/* Pixel 1 */
|
||||
y = *ysrc++;
|
||||
|
||||
red1 = RYFAC * y + rc;
|
||||
green1 = GYFAC * y + gc;
|
||||
blue1 = BYFAC * y + bc;
|
||||
|
||||
/* Pixel 2 */
|
||||
y = *ysrc++;
|
||||
red2 = RYFAC * y + rc;
|
||||
green2 = GYFAC * y + gc;
|
||||
blue2 = BYFAC * y + bc;
|
||||
|
||||
/* Since out of bounds errors are relatively rare, we check two
|
||||
pixels at once to see if any components are out of bounds, and
|
||||
then fix whichever is broken. This works due to high values and
|
||||
negative values both becoming larger than the cutoff when
|
||||
casted to unsigned. And ORing them together checks all of them
|
||||
simultaneously. */
|
||||
if (((unsigned)(red1 | green1 | blue1 |
|
||||
red2 | green2 | blue2)) > (RYFAC*255+ROUNDOFFS)) {
|
||||
if (((unsigned)(red1 | green1 | blue1)) >
|
||||
(RYFAC*255+ROUNDOFFS)) {
|
||||
if ((unsigned)red1 > (RYFAC*255+ROUNDOFFS))
|
||||
{
|
||||
if (red1 < 0)
|
||||
red1 = 0;
|
||||
else
|
||||
red1 = (RYFAC*255+ROUNDOFFS);
|
||||
}
|
||||
if ((unsigned)green1 > (GYFAC*255+ROUNDOFFSG))
|
||||
{
|
||||
if (green1 < 0)
|
||||
green1 = 0;
|
||||
else
|
||||
green1 = (GYFAC*255+ROUNDOFFSG);
|
||||
}
|
||||
if ((unsigned)blue1 > (BYFAC*255+ROUNDOFFS))
|
||||
{
|
||||
if (blue1 < 0)
|
||||
blue1 = 0;
|
||||
else
|
||||
blue1 = (BYFAC*255+ROUNDOFFS);
|
||||
}
|
||||
}
|
||||
|
||||
if (((unsigned)(red2 | green2 | blue2)) >
|
||||
(RYFAC*255+ROUNDOFFS)) {
|
||||
if ((unsigned)red2 > (RYFAC*255+ROUNDOFFS))
|
||||
{
|
||||
if (red2 < 0)
|
||||
red2 = 0;
|
||||
else
|
||||
red2 = (RYFAC*255+ROUNDOFFS);
|
||||
}
|
||||
if ((unsigned)green2 > (GYFAC*255+ROUNDOFFSG))
|
||||
{
|
||||
if (green2 < 0)
|
||||
green2 = 0;
|
||||
else
|
||||
green2 = (GYFAC*255+ROUNDOFFSG);
|
||||
}
|
||||
if ((unsigned)blue2 > (BYFAC*255+ROUNDOFFS))
|
||||
{
|
||||
if (blue2 < 0)
|
||||
blue2 = 0;
|
||||
else
|
||||
blue2 = (BYFAC*255+ROUNDOFFS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rbits = red1 >> 16 ;
|
||||
gbits = green1 >> 15 ;
|
||||
bbits = blue1 >> 16 ;
|
||||
lcd_send_data((rbits << 11) | (gbits << 5) | bbits);
|
||||
|
||||
rbits = red2 >> 16 ;
|
||||
gbits = green2 >> 15 ;
|
||||
bbits = blue2 >> 16 ;
|
||||
lcd_send_data((rbits << 11) | (gbits << 5) | bbits);
|
||||
}
|
||||
while (ysrc < row_end);
|
||||
|
||||
src_y++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Update a fraction of the display. */
|
||||
void lcd_update_rect(int x0, int y0, int width, int height)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,9 +30,6 @@
|
|||
#endif
|
||||
|
||||
/* Display status */
|
||||
#if MEMORYSIZE > 2
|
||||
static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
|
||||
#endif
|
||||
static bool is_lcd_enabled = true;
|
||||
|
||||
/* LCD command set for Samsung S6B33B2 */
|
||||
|
|
@ -301,80 +298,6 @@ void lcd_set_flip(bool yesno)
|
|||
|
||||
/*** update functions ***/
|
||||
|
||||
#if MEMORYSIZE > 2 /* not for C200V2 */
|
||||
void lcd_yuv_set_options(unsigned options)
|
||||
{
|
||||
lcd_yuv_options = options;
|
||||
}
|
||||
|
||||
/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
|
||||
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride);
|
||||
extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride,
|
||||
int x_screen, /* To align dither pattern */
|
||||
int y_screen);
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
unsigned char const * yuv_src[3];
|
||||
off_t z;
|
||||
|
||||
/* Sorry, but width and height must be >= 2 or else */
|
||||
width &= ~1;
|
||||
height >>= 1;
|
||||
|
||||
y += 0x1a;
|
||||
|
||||
z = stride*src_y;
|
||||
yuv_src[0] = src[0] + z + src_x;
|
||||
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
|
||||
lcd_send_command(R_ENTRY_MODE, 0x80);
|
||||
|
||||
lcd_send_command(R_X_ADDR_AREA, x);
|
||||
lcd_send_command(x + width - 1, 0);
|
||||
|
||||
if (lcd_yuv_options & LCD_YUV_DITHER)
|
||||
{
|
||||
do
|
||||
{
|
||||
lcd_send_command(R_Y_ADDR_AREA, y);
|
||||
lcd_send_command(y + 1, 0);
|
||||
|
||||
lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y);
|
||||
|
||||
yuv_src[0] += stride << 1; /* Skip down two luma lines */
|
||||
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
|
||||
yuv_src[2] += stride >> 1;
|
||||
y += 2;
|
||||
}
|
||||
while (--height > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
lcd_send_command(R_Y_ADDR_AREA, y);
|
||||
lcd_send_command(y + 1, 0);
|
||||
|
||||
lcd_write_yuv420_lines(yuv_src, width, stride);
|
||||
|
||||
yuv_src[0] += stride << 1; /* Skip down two luma lines */
|
||||
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
|
||||
yuv_src[2] += stride >> 1;
|
||||
y += 2;
|
||||
}
|
||||
while (--height > 0);
|
||||
}
|
||||
}
|
||||
#endif /* MEMORYSIZE > 2 */
|
||||
|
||||
/* Update the display.
|
||||
This must be called after all other LCD functions that change the display. */
|
||||
void lcd_update(void)
|
||||
|
|
|
|||
|
|
@ -1,556 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id:$
|
||||
*
|
||||
* Copyright (C) 2007-2008 by Michael Sevakis
|
||||
* Adapted for the Packard Bell Vibe 500 by Szymon Dziok
|
||||
*
|
||||
* Packard Bell Vibe 500 LCD assembly routines
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Scaled, normalized, rounded and tweaked to yield RGB 565:
|
||||
* |R| |74 0 101| |Y' - 16| >> 9
|
||||
* |G| = |74 -24 -51| |Cb - 128| >> 8
|
||||
* |B| |74 128 0| |Cr - 128| >> 9
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines
|
||||
.type lcd_write_yuv420_lines, %function
|
||||
lcd_write_yuv420_lines:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
stmfd sp!, { r4-r11, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@
|
||||
ldr r0, =LCD1_BASE @
|
||||
@
|
||||
sub r2, r2, #1 @ Adjust stride because of increment
|
||||
10: @ loop line @
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
|
||||
add r7, r12, r7, asl #5 @ by one less when adding - same for all
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
|
||||
add r10, r10, r10, asl #4 @
|
||||
add r10, r10, r8, asl #3 @
|
||||
add r10, r10, r8, asl #4 @
|
||||
@
|
||||
add r11, r9, r9, asl #2 @ r9 = Cr*101
|
||||
add r11, r11, r9, asl #5 @
|
||||
add r9, r11, r9, asl #6 @
|
||||
@
|
||||
add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
|
||||
mov r8, r8, asr #2 @
|
||||
add r9, r9, #256 @ r9 = rv = (r8 + 256) >> 9
|
||||
mov r9, r9, asr #9 @
|
||||
rsb r10, r10, #128 @ r10 = guv = (-r9 + 128) >> 8
|
||||
mov r10, r10, asr #8 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
|
||||
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
|
||||
@
|
||||
movs r7, r3, lsr #8 @ store pixel
|
||||
20: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0, #0x10] @
|
||||
25: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 25b @
|
||||
str r3, [r0, #0x10] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
@
|
||||
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
|
||||
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
|
||||
@
|
||||
movs r7, r3, lsr #8 @ store pixel
|
||||
20: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0, #0x10] @
|
||||
25: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 25b @
|
||||
str r3, [r0, #0x10] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
orr r3, r3, r7, lsl #5 @ r3 = b | (g << 5)
|
||||
orr r3, r3, r11, lsl #11 @ r3 |= (r << 11)
|
||||
@
|
||||
movs r7, r3, lsr #8 @ store pixel
|
||||
20: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0, #0x10] @
|
||||
25: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 25b @
|
||||
str r3, [r0, #0x10] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
|
||||
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
|
||||
@
|
||||
movs r7, r3, lsr #8 @ store pixel
|
||||
20: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0, #0x10] @
|
||||
25: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 25b @
|
||||
str r3, [r0, #0x10] @
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r11 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride,
|
||||
* int x_screen,
|
||||
* int y_screen);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Red scaled at twice g & b but at same precision to place it in correct
|
||||
* bit position after multiply and leave instruction count lower.
|
||||
* |R| |258 0 408| |Y' - 16|
|
||||
* |G| = |149 -49 -104| |Cb - 128|
|
||||
* |B| |149 258 0| |Cr - 128|
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*
|
||||
* Kernel pattern (raw|use order):
|
||||
* 5 3 4 2 row0 row2 > down
|
||||
* 1 7 0 6 | 5 1 3 7 4 0 2 6 col0 left
|
||||
* 4 2 5 3 | 4 0 2 6 5 1 3 7 col2 \/
|
||||
* 0 6 1 7
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines_odither
|
||||
.type lcd_write_yuv420_lines_odither, %function
|
||||
lcd_write_yuv420_lines_odither:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
@ r3 = x_screen
|
||||
@ [sp] = y_screen
|
||||
stmfd sp!, { r4-r11, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@
|
||||
ldr r0, [sp, #36] @ Line up pattern and kernel quadrant
|
||||
eor r14, r3, r0 @
|
||||
and r14, r14, #0x2 @
|
||||
mov r14, r14, lsl #6 @ 0x00 or 0x80
|
||||
@
|
||||
ldr r0, =LCD1_BASE @
|
||||
@
|
||||
sub r2, r2, #1 @ Adjust stride because of increment
|
||||
10: @ loop line @
|
||||
@
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
eor r14, r14, #0x80 @ flip pattern quadrant
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
|
||||
add r10, r10, r8, asl #5 @
|
||||
add r10, r10, r9, asl #3 @
|
||||
add r10, r10, r9, asl #5 @
|
||||
add r10, r10, r9, asl #6 @
|
||||
@
|
||||
mov r8, r8, asl #1 @ r8 = bu = Cb*258
|
||||
add r8, r8, r8, asl #7 @
|
||||
@
|
||||
add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
|
||||
add r9, r9, r9, asl #4 @
|
||||
mov r9, r9, asl #3 @
|
||||
@
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x200 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
movs r7, r3, lsr #8 @ store pixel
|
||||
20: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0, #0x10] @
|
||||
25: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 25b @
|
||||
str r3, [r0, #0x10] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
@ This element is zero - use r14 @
|
||||
@
|
||||
add r3, r3, r14 @ b = r3 + delta
|
||||
add r11, r11, r14, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r14, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
movs r7, r3, lsr #8 @ store pixel
|
||||
20: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0, #0x10] @
|
||||
25: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 25b @
|
||||
str r3, [r0, #0x10] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x100 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
movs r7, r3, lsr #8 @ store pixel
|
||||
20: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0, #0x10] @
|
||||
25: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 25b @
|
||||
str r3, [r0, #0x10] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x300 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
movs r7, r3, lsr #8 @ store pixel
|
||||
20: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0, #0x10] @
|
||||
25: @
|
||||
ldr r11, [r0] @
|
||||
tst r11, #LCD1_BUSY_MASK @
|
||||
bne 25b @
|
||||
str r3, [r0, #0x10] @
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r11 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
|
||||
|
|
@ -35,8 +35,6 @@ static unsigned short disp_control_rev;
|
|||
/* Contrast setting << 8 */
|
||||
static int lcd_contrast;
|
||||
|
||||
static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
|
||||
|
||||
/* Forward declarations */
|
||||
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
|
||||
static void lcd_display_off(void);
|
||||
|
|
@ -377,79 +375,6 @@ bool lcd_active(void)
|
|||
|
||||
/*** update functions ***/
|
||||
|
||||
void lcd_yuv_set_options(unsigned options)
|
||||
{
|
||||
lcd_yuv_options = options;
|
||||
}
|
||||
|
||||
/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
|
||||
|
||||
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride);
|
||||
extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride,
|
||||
int x_screen, /* To align dither pattern */
|
||||
int y_screen);
|
||||
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
const unsigned char *yuv_src[3];
|
||||
const unsigned char *ysrc_max;
|
||||
int y0;
|
||||
int options;
|
||||
|
||||
if (!display_on)
|
||||
return;
|
||||
|
||||
width &= ~1;
|
||||
height &= ~1;
|
||||
|
||||
lcd_write_reg(R_VERT_RAM_ADDR_POS, ((LCD_WIDTH - 1 - x) << 8) |
|
||||
((LCD_WIDTH-1) - (x + width - 1)));
|
||||
|
||||
y0 = LCD_HEIGHT - 1 - y;
|
||||
|
||||
lcd_write_reg(R_ENTRY_MODE,0x1000);
|
||||
|
||||
yuv_src[0] = src[0] + src_y * stride + src_x;
|
||||
yuv_src[1] = src[1] + (src_y * stride >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
ysrc_max = yuv_src[0] + height * stride;
|
||||
|
||||
options = lcd_yuv_options;
|
||||
|
||||
do
|
||||
{
|
||||
lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (y0 << 8) | (y0 - 1));
|
||||
lcd_write_reg(R_RAM_ADDR_SET, ((LCD_WIDTH - 1 - x) << 8) | y0);
|
||||
|
||||
/* start drawing */
|
||||
lcd_send_cmd(R_WRITE_DATA_2_GRAM);
|
||||
|
||||
if (options & LCD_YUV_DITHER)
|
||||
{
|
||||
lcd_write_yuv420_lines_odither(yuv_src, width, stride,x, y);
|
||||
y -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd_write_yuv420_lines(yuv_src, width, stride);
|
||||
}
|
||||
|
||||
y0 -= 2;
|
||||
yuv_src[0] += stride << 1;
|
||||
yuv_src[1] += stride >> 1;
|
||||
yuv_src[2] += stride >> 1;
|
||||
}
|
||||
while (yuv_src[0] < ysrc_max);
|
||||
lcd_write_reg(R_ENTRY_MODE,0x1008);
|
||||
}
|
||||
|
||||
/* Update a fraction of the display. */
|
||||
void lcd_update_rect(int x0, int y0, int width, int height)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,570 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007-2008 by Michael Sevakis
|
||||
*
|
||||
* H10 20GB LCD assembly routines
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Scaled, normalized, rounded and tweaked to yield RGB 565:
|
||||
* |R| |74 0 101| |Y' - 16| >> 9
|
||||
* |G| = |74 -24 -51| |Cb - 128| >> 8
|
||||
* |B| |74 128 0| |Cr - 128| >> 9
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines
|
||||
.type lcd_write_yuv420_lines, %function
|
||||
lcd_write_yuv420_lines:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
stmfd sp!, { r4-r11, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@
|
||||
mov r0, #0x7000000c @ r0 = &LCD2_PORT = 0x70008a0c
|
||||
add r0, r0, #0x8a00 @
|
||||
mov r14, #LCD2_DATA_MASK @
|
||||
@
|
||||
sub r2, r2, #1 @ Adjust stride because of increment
|
||||
10: @ loop line @
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
|
||||
add r7, r12, r7, asl #5 @ by one less when adding - same for all
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
|
||||
add r10, r10, r10, asl #4 @
|
||||
add r10, r10, r8, asl #3 @
|
||||
add r10, r10, r8, asl #4 @
|
||||
@
|
||||
add r11, r9, r9, asl #2 @ r9 = Cr*101
|
||||
add r11, r11, r9, asl #5 @
|
||||
add r9, r11, r9, asl #6 @
|
||||
@
|
||||
add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
|
||||
mov r8, r8, asr #2 @
|
||||
add r9, r9, #256 @ r9 = rv = (r8 + 256) >> 9
|
||||
mov r9, r9, asr #9 @
|
||||
rsb r10, r10, #128 @ r10 = guv = (-r9 + 128) >> 8
|
||||
mov r10, r10, asr #8 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
|
||||
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
|
||||
@
|
||||
orr r7, r14, r3, lsr #8 @ store pixel
|
||||
orr r11, r14, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
@
|
||||
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
|
||||
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
|
||||
@
|
||||
orr r7, r14, r3, lsr #8 @ store pixel
|
||||
orr r11, r14, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
orr r3, r3, r7, lsl #5 @ r3 = b | (g << 5)
|
||||
orr r3, r3, r11, lsl #11 @ r3 |= (r << 11)
|
||||
@
|
||||
orr r7, r14, r3, lsr #8 @ store pixel
|
||||
orr r11, r14, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
|
||||
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
|
||||
@
|
||||
orr r7, r14, r3, lsr #8 @ store pixel
|
||||
orr r11, r14, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r11, [r0] @
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r11 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride,
|
||||
* int x_screen,
|
||||
* int y_screen);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Red scaled at twice g & b but at same precision to place it in correct
|
||||
* bit position after multiply and leave instruction count lower.
|
||||
* |R| |258 0 408| |Y' - 16|
|
||||
* |G| = |149 -49 -104| |Cb - 128|
|
||||
* |B| |149 258 0| |Cr - 128|
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*
|
||||
* Kernel pattern (raw|use order):
|
||||
* 5 3 4 2 row0 row2 > down
|
||||
* 1 7 0 6 | 5 1 3 7 4 0 2 6 col0 left
|
||||
* 4 2 5 3 | 4 0 2 6 5 1 3 7 col2 \/
|
||||
* 0 6 1 7
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines_odither
|
||||
.type lcd_write_yuv420_lines_odither, %function
|
||||
lcd_write_yuv420_lines_odither:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
@ r3 = x_screen
|
||||
@ [sp] = y_screen
|
||||
stmfd sp!, { r4-r11, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@
|
||||
ldr r0, [sp, #36] @ Line up pattern and kernel quadrant
|
||||
eor r14, r3, r0 @
|
||||
and r14, r14, #0x2 @
|
||||
mov r14, r14, lsl #6 @ 0x00 or 0x80
|
||||
@
|
||||
mov r0, #0x7000000c @ r0 = &LCD2_PORT = 0x70008a0c
|
||||
add r0, r0, #0x8a00 @
|
||||
@
|
||||
sub r2, r2, #1 @ Adjust stride because of increment
|
||||
10: @ loop line @
|
||||
@
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
eor r14, r14, #0x80 @ flip pattern quadrant
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
|
||||
add r10, r10, r8, asl #5 @
|
||||
add r10, r10, r9, asl #3 @
|
||||
add r10, r10, r9, asl #5 @
|
||||
add r10, r10, r9, asl #6 @
|
||||
@
|
||||
mov r8, r8, asl #1 @ r8 = bu = Cb*258
|
||||
add r8, r8, r8, asl #7 @
|
||||
@
|
||||
add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
|
||||
add r9, r9, r9, asl #4 @
|
||||
mov r9, r9, asl #3 @
|
||||
@
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x200 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
mov r11, #LCD2_DATA_MASK @ store pixel
|
||||
orr r7, r11, r3, lsr #8 @
|
||||
orr r11, r11, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
@ This element is zero - use r14 @
|
||||
@
|
||||
add r3, r3, r14 @ b = r3 + delta
|
||||
add r11, r11, r14, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r14, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
mov r11, #LCD2_DATA_MASK @ store pixel
|
||||
orr r7, r11, r3, lsr #8 @
|
||||
orr r11, r11, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x100 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
mov r11, #LCD2_DATA_MASK @ store pixel
|
||||
orr r7, r11, r3, lsr #8 @
|
||||
orr r11, r11, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x300 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
mov r11, #LCD2_DATA_MASK @ store pixel
|
||||
orr r7, r11, r3, lsr #8 @
|
||||
orr r11, r11, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r11, [r0] @
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r11 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
|
||||
|
|
@ -81,7 +81,6 @@
|
|||
static bool lcd_enabled;
|
||||
|
||||
/* Display status */
|
||||
static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
|
||||
static unsigned mad_ctrl = 0;
|
||||
|
||||
/* wait for LCD */
|
||||
|
|
@ -313,86 +312,6 @@ void lcd_set_flip(bool yesno)
|
|||
lcd_send_data(mad_ctrl);
|
||||
}
|
||||
|
||||
void lcd_yuv_set_options(unsigned options)
|
||||
{
|
||||
lcd_yuv_options = options;
|
||||
}
|
||||
|
||||
/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
|
||||
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
int width, int stride);
|
||||
|
||||
extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
int width, int stride,
|
||||
int x_screen, int y_screen);
|
||||
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
unsigned char const * yuv_src[3];
|
||||
off_t z;
|
||||
|
||||
/* Sorry, but width and height must be >= 2 or else */
|
||||
width &= ~1;
|
||||
height >>= 1;
|
||||
|
||||
z = stride*src_y;
|
||||
yuv_src[0] = src[0] + z + src_x;
|
||||
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
|
||||
/* Set vertical address mode */
|
||||
lcd_send_cmd(MADCTR);
|
||||
lcd_send_data(mad_ctrl | (1<<5));
|
||||
|
||||
lcd_send_cmd(RASET);
|
||||
lcd_send_data(x);
|
||||
lcd_send_data(x + width - 1);
|
||||
|
||||
if (lcd_yuv_options & LCD_YUV_DITHER)
|
||||
{
|
||||
do
|
||||
{
|
||||
lcd_send_cmd(CASET);
|
||||
lcd_send_data(y);
|
||||
lcd_send_data(y + 1);
|
||||
|
||||
lcd_send_cmd(RAMWR);
|
||||
|
||||
lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y);
|
||||
yuv_src[0] += stride << 1; /* Skip down two luma lines */
|
||||
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
|
||||
yuv_src[2] += stride >> 1;
|
||||
y += 2;
|
||||
}
|
||||
while (--height > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
lcd_send_cmd(CASET);
|
||||
lcd_send_data(y);
|
||||
lcd_send_data(y + 1);
|
||||
|
||||
lcd_send_cmd(RAMWR);
|
||||
|
||||
lcd_write_yuv420_lines(yuv_src, width, stride);
|
||||
yuv_src[0] += stride << 1; /* Skip down two luma lines */
|
||||
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
|
||||
yuv_src[2] += stride >> 1;
|
||||
y += 2;
|
||||
}
|
||||
while (--height > 0);
|
||||
}
|
||||
|
||||
/* Restore the address mode */
|
||||
lcd_send_cmd(MADCTR);
|
||||
lcd_send_data(mad_ctrl);
|
||||
}
|
||||
|
||||
/* Update the display.
|
||||
This must be called after all other LCD functions that change the display. */
|
||||
void lcd_update(void)
|
||||
|
|
|
|||
|
|
@ -1,140 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id:$
|
||||
*
|
||||
* Copyright (C) 2010 by Szymon Dziok
|
||||
*
|
||||
* Philips Gogear HDD6330 LCD assembly routine
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/****************************************************************************
|
||||
void lcd_yuv_write_inner_loop(unsigned char const * const ysrc,
|
||||
unsigned char const * const usrc,
|
||||
unsigned char const * const vsrc,
|
||||
int width);
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_yuv_write_inner_loop
|
||||
.type lcd_yuv_write_inner_loop, %function
|
||||
lcd_yuv_write_inner_loop:
|
||||
@ r0 = ysrc
|
||||
@ r1 = usrc
|
||||
@ r2 = vsrc
|
||||
@ r3 = width
|
||||
stmfd sp!, { r4-r11, lr } @ save regs
|
||||
mov r4, #0x70000000 @ r4 = LCD2_BLOCK_CTRL - 0x20
|
||||
add r4, r4, #0x8a00 @
|
||||
add r5, r4, #0x100 @ r5 = LCD2_BLOCK_DATA
|
||||
10: @ loop
|
||||
|
||||
ldrb r7, [r1], #1 @ *usrc++
|
||||
ldrb r8, [r2], #1 @ *vsrc++
|
||||
|
||||
sub r7, r7, #128 @ Cb -= 128
|
||||
sub r8, r8, #128 @ Cr -= 128
|
||||
|
||||
add r10, r8, r8, asl #2 @ Cr*101
|
||||
add r10, r10, r8, asl #5
|
||||
add r10, r10, r8, asl #6
|
||||
|
||||
add r11, r8, r8, asl #1 @ Cr*51 + Cb*24
|
||||
add r11, r11, r11, asl #4
|
||||
add r11, r11, r7, asl #3
|
||||
add r11, r11, r7, asl #4
|
||||
|
||||
add r12, r7, #2 @ r12 = bu = (Cb*128 + 256) >> 9
|
||||
mov r12, r12, asr #2
|
||||
add r10, r10, #256 @ r10 = rv = (Cr*101 + 256) >> 9
|
||||
mov r10, r10, asr #9
|
||||
rsb r11, r11, #128 @ r11 = guv = (-r11 + 128) >> 8
|
||||
mov r11, r11, asr #8
|
||||
|
||||
@ pixel_1
|
||||
ldrb r7, [r0], #1 @ *ysrc++
|
||||
sub r7, r7, #16 @ Y = (Y' - 16) * 37
|
||||
add r8, r7, r7, asl #2
|
||||
add r7, r8, r7, asl #5
|
||||
|
||||
add r9, r10, r7, asr #8 @ R = (Y >> 8) + rv
|
||||
add r8, r11, r7, asr #7 @ G = (Y >> 7) + guv
|
||||
add r7, r12, r7, asr #8 @ B = (Y >> 8) + bu
|
||||
|
||||
cmp r9, #31 @ clamp R
|
||||
mvnhi r9, r9, asr #31
|
||||
andhi r9, r9, #31
|
||||
|
||||
cmp r8, #63 @ clamp G
|
||||
mvnhi r8, r8, asr #31
|
||||
andhi r8, r8, #63
|
||||
|
||||
cmp r7, #31 @ clamp B
|
||||
mvnhi r7, r7, asr #31
|
||||
andhi r7, r7, #31
|
||||
|
||||
orr r6, r7, r8, lsl #5 @ pack pixel
|
||||
orr r6, r6, r9, lsl #11
|
||||
|
||||
mov r7, r6, lsl #8 @ swap bytes
|
||||
and r7, r7, #0xff00
|
||||
add r6, r7, r6, lsr #8
|
||||
|
||||
@ pixel_2
|
||||
ldrb r7, [r0], #1 @ *ysrc++
|
||||
sub r7, r7, #16 @ Y = (Y' - 16) * 37
|
||||
add r8, r7, r7, asl #2
|
||||
add r7, r8, r7, asl #5
|
||||
|
||||
add r9, r10, r7, asr #8 @ R = (Y >> 8) + rv
|
||||
add r8, r11, r7, asr #7 @ G = (Y >> 7) + guv
|
||||
add r7, r12, r7, asr #8 @ B = (Y >> 8) + bu
|
||||
|
||||
cmp r9, #31 @ clamp R
|
||||
mvnhi r9, r9, asr #31
|
||||
andhi r9, r9, #31
|
||||
|
||||
cmp r8, #63 @ clamp G
|
||||
mvnhi r8, r8, asr #31
|
||||
andhi r8, r8, #63
|
||||
|
||||
cmp r7, #31 @ clamp B
|
||||
mvnhi r7, r7, asr #31
|
||||
andhi r7, r7, #31
|
||||
|
||||
orr r7, r7, r8, lsl #5 @ pack pixel
|
||||
orr r7, r7, r9, lsl #11
|
||||
|
||||
orr r6, r6, r7, lsl #24 @ swap bytes and add pixels simultaneously
|
||||
mov r7, r7, lsr #8
|
||||
orr r6, r6, r7, lsl #16
|
||||
|
||||
11: @ while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK));
|
||||
ldr r11, [r4, #0x20] @
|
||||
tst r11, #0x1000000 @
|
||||
beq 11b @
|
||||
|
||||
str r6, [r5] @ send two pixels
|
||||
|
||||
subs r3, r3, #2 @ decrease width
|
||||
bgt 10b @ loop
|
||||
|
||||
ldmpc regs=r4-r11 @ restore regs
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_yuv_write_inner_loop, .-lcd_yuv_write_inner_loop
|
||||
|
|
@ -37,9 +37,6 @@
|
|||
/* whether the lcd is currently enabled or not */
|
||||
static bool lcd_enabled;
|
||||
|
||||
/* Display status */
|
||||
static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
|
||||
|
||||
/* Value used for flipping. Must be remembered when display is turned off. */
|
||||
static unsigned short flip;
|
||||
|
||||
|
|
@ -147,101 +144,6 @@ void lcd_set_flip(bool yesno)
|
|||
lcd_send_data(0x08 | flip);
|
||||
}
|
||||
|
||||
void lcd_yuv_set_options(unsigned options)
|
||||
{
|
||||
lcd_yuv_options = options;
|
||||
}
|
||||
|
||||
#define CSUB_X 2
|
||||
#define CSUB_Y 2
|
||||
|
||||
/* YUV- > RGB565 conversion
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Scaled, normalized, rounded and tweaked to yield RGB 565:
|
||||
* |R| |74 0 101| |Y' - 16| >> 9
|
||||
* |G| = |74 -24 -51| |Cb - 128| >> 8
|
||||
* |B| |74 128 0| |Cr - 128| >> 9
|
||||
*/
|
||||
|
||||
extern void lcd_yuv_write_inner_loop(unsigned char const * const ysrc,
|
||||
unsigned char const * const usrc,
|
||||
unsigned char const * const vsrc,
|
||||
int width);
|
||||
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
int h;
|
||||
|
||||
width = (width + 1) & ~1;
|
||||
|
||||
lcd_send_reg(LCD_REG_HORIZ_ADDR_START);
|
||||
lcd_send_data(y);
|
||||
|
||||
lcd_send_reg(LCD_REG_HORIZ_ADDR_END);
|
||||
lcd_send_data(y + height - 1);
|
||||
|
||||
lcd_send_reg(LCD_REG_VERT_ADDR_START);
|
||||
lcd_send_data(x + x_offset);
|
||||
|
||||
lcd_send_reg(LCD_REG_VERT_ADDR_END);
|
||||
lcd_send_data(x + width - 1 + x_offset);
|
||||
|
||||
lcd_send_reg(LCD_REG_WRITE_DATA_2_GRAM);
|
||||
|
||||
const int stride_div_csub_x = stride/CSUB_X;
|
||||
|
||||
h=0;
|
||||
while (1)
|
||||
{
|
||||
/* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
|
||||
const unsigned char *ysrc = src[0] + stride * src_y + src_x;
|
||||
|
||||
const int uvoffset = stride_div_csub_x * (src_y/CSUB_Y) +
|
||||
(src_x/CSUB_X);
|
||||
|
||||
const unsigned char *usrc = src[1] + uvoffset;
|
||||
const unsigned char *vsrc = src[2] + uvoffset;
|
||||
|
||||
int pixels_to_write;
|
||||
|
||||
if (h==0)
|
||||
{
|
||||
while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
|
||||
LCD2_BLOCK_CONFIG = 0;
|
||||
|
||||
if (height == 0) break;
|
||||
|
||||
pixels_to_write = (width * height) * 2;
|
||||
h = height;
|
||||
|
||||
/* calculate how much we can do in one go */
|
||||
if (pixels_to_write > 0x10000)
|
||||
{
|
||||
h = (0x10000/2) / width;
|
||||
pixels_to_write = (width * h) * 2;
|
||||
}
|
||||
|
||||
height -= h;
|
||||
LCD2_BLOCK_CTRL = 0x10000080;
|
||||
LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
|
||||
LCD2_BLOCK_CTRL = 0x34000000;
|
||||
}
|
||||
|
||||
lcd_yuv_write_inner_loop(ysrc,usrc,vsrc,width);
|
||||
|
||||
src_y++;
|
||||
h--;
|
||||
}
|
||||
|
||||
while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
|
||||
LCD2_BLOCK_CONFIG = 0;
|
||||
}
|
||||
|
||||
/* Update the display.
|
||||
This must be called after all other LCD functions that change the display. */
|
||||
void lcd_update(void)
|
||||
|
|
|
|||
|
|
@ -1,590 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007-2011 by Michael Sevakis
|
||||
*
|
||||
* Philips GoGear SA9200 LCD assembly routines
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* This code should work in general for a Renesas type LCD interface
|
||||
* connected to the "mono" bridge. TODO: Share it where possible.
|
||||
*
|
||||
* Dither is already prepared to be built for upright and rotated
|
||||
* orientations. */
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Scaled, normalized, rounded and tweaked to yield RGB 565:
|
||||
* |R| |74 0 101| |Y' - 16| >> 9
|
||||
* |G| = |74 -24 -51| |Cb - 128| >> 8
|
||||
* |B| |74 128 0| |Cr - 128| >> 9
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines
|
||||
.type lcd_write_yuv420_lines, %function
|
||||
lcd_write_yuv420_lines:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
stmfd sp!, { r4-r10, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@
|
||||
mov r0, #0x70000000 @ r0 = LCD1_BASE_ADDR = 0x70003000
|
||||
orr r0, r0, #0x3000 @
|
||||
@
|
||||
sub r2, r2, #1 @ Adjust stride because of increment
|
||||
10: @ loop line @
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
|
||||
add r7, r12, r7, asl #5 @ by one less when adding - same for all
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
|
||||
add r10, r10, r10, asl #4 @
|
||||
add r10, r10, r8, asl #3 @
|
||||
add r10, r10, r8, asl #4 @
|
||||
@
|
||||
add r14, r9, r9, asl #2 @ r9 = Cr*101
|
||||
add r14, r14, r9, asl #5 @
|
||||
add r9, r14, r9, asl #6 @
|
||||
@
|
||||
add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
|
||||
mov r8, r8, asr #2 @
|
||||
add r9, r9, #256 @ r9 = rv = (r8 + 256) >> 9
|
||||
mov r9, r9, asr #9 @
|
||||
rsb r10, r10, #128 @ r10 = guv = (-r9 + 128) >> 8
|
||||
mov r10, r10, asr #8 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r14, r9, r7, asr #8 @ r14 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r14 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r14, #31 @ clamp r
|
||||
mvnhi r14, r14, asr #31 @
|
||||
andhi r14, r14, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
orr r7, r3, r7, lsl #5 @ r7 = |00000000|00000000|00000ggg|gggbbbbb|
|
||||
orr r7, r7, r14, lsl #11 @ r7 = |00000000|00000000|rrrrrggg|gggbbbbb|
|
||||
mov r14, r7, lsr #8 @ r14 = |00000000|00000000|00000000|rrrrrggg|
|
||||
@
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r14, [r0, #0x10] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r7, [r0, #0x10] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r14, r9, r7, asr #8 @ r14 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r14 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r14, #31 @ clamp r
|
||||
mvnhi r14, r14, asr #31 @
|
||||
andhi r14, r14, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
@
|
||||
orr r7, r3, r7, lsl #5 @ r7 = |00000000|00000000|00000ggg|gggbbbbb|
|
||||
orr r7, r7, r14, lsl #11 @ r7 = |00000000|00000000|rrrrrggg|gggbbbbb|
|
||||
mov r14, r7, lsr #8 @ r14 = |00000000|00000000|00000000|rrrrrggg|
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r14, [r0, #0x10] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r7, [r0, #0x10] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r14, r9, r7, asr #8 @ r14 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r14 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r14, #31 @ clamp r
|
||||
mvnhi r14, r14, asr #31 @
|
||||
andhi r14, r14, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
orr r7, r3, r7, lsl #5 @ r7 = |00000000|00000000|00000ggg|gggbbbbb|
|
||||
orr r7, r7, r14, lsl #11 @ r7 = |00000000|00000000|rrrrrggg|gggbbbbb|
|
||||
mov r14, r7, lsr #8 @ r14 = |00000000|00000000|00000000|rrrrrggg|
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r14, [r0, #0x10] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r7, [r0, #0x10] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r14, r9, r7, asr #8 @ r14 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r14 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r14, #31 @ clamp r
|
||||
mvnhi r14, r14, asr #31 @
|
||||
andhi r14, r14, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
orr r7, r3, r7, lsl #5 @ r7 = |00000000|00000000|00000ggg|gggbbbbb|
|
||||
orr r7, r7, r14, lsl #11 @ r7 = |00000000|00000000|rrrrrggg|gggbbbbb|
|
||||
mov r14, r7, lsr #8 @ r14 = |00000000|00000000|00000000|rrrrrggg|
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r14, [r0, #0x10] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r7, [r0, #0x10] @
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r10 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride,
|
||||
* int x_screen,
|
||||
* int y_screen);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Red scaled at twice g & b but at same precision to place it in correct
|
||||
* bit position after multiply and leave instruction count lower.
|
||||
* |R| |258 0 408| |Y' - 16|
|
||||
* |G| = |149 -49 -104| |Cb - 128|
|
||||
* |B| |149 258 0| |Cr - 128|
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > right/down
|
||||
* 2 4 \/ down/left
|
||||
*
|
||||
* Kernel pattern for upright display:
|
||||
* 5 3 4 2 +-> right
|
||||
* 1 7 0 6 | down
|
||||
* 4 2 5 3 \/
|
||||
* 0 6 1 7
|
||||
*
|
||||
* Kernel pattern for clockwise rotated display:
|
||||
* 2 6 3 7 +-> down
|
||||
* 4 0 5 1 | left
|
||||
* 3 7 2 6 \/
|
||||
* 5 1 4 0
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines_odither
|
||||
.type lcd_write_yuv420_lines_odither, %function
|
||||
lcd_write_yuv420_lines_odither:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = strideS
|
||||
@ r3 = x_screen
|
||||
@ [sp] = y_screen
|
||||
stmfd sp!, { r4-r11, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@
|
||||
ldr r0, [sp, #36] @ Line up pattern and kernel quadrant
|
||||
eor r14, r3, r0 @
|
||||
and r14, r14, #0x2 @
|
||||
mov r14, r14, lsl #6 @ 0x00 or 0x80
|
||||
@
|
||||
mov r0, #0x70000000 @ r0 = LCD1_BASE_ADDR = 0x70003000
|
||||
orr r0, r0, #0x3000 @
|
||||
@
|
||||
sub r2, r2, #1 @ Adjust stride because of increment
|
||||
10: @ loop line @
|
||||
@
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
eor r14, r14, #0x80 @ flip pattern quadrant
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
|
||||
add r10, r10, r8, asl #5 @
|
||||
add r10, r10, r9, asl #3 @
|
||||
add r10, r10, r9, asl #5 @
|
||||
add r10, r10, r9, asl #6 @
|
||||
@
|
||||
mov r8, r8, asl #1 @ r8 = bu = Cb*258
|
||||
add r8, r8, r8, asl #7 @
|
||||
@
|
||||
add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
|
||||
add r9, r9, r9, asl #4 @
|
||||
mov r9, r9, asl #3 @
|
||||
@
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
#if LCD_WIDTH >= LCD_HEIGHT
|
||||
add r12, r14, #0x200 @
|
||||
#else
|
||||
add r12, r14, #0x100 @
|
||||
#endif
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
and r11, r11, #0xf800 @ r11 = |00000000|00000000|rrrrrggg|gggbbbbb|
|
||||
and r7, r7, #0x7e00 @
|
||||
orr r11, r11, r7, lsr #4 @
|
||||
orr r11, r11, r3, lsr #10 @
|
||||
mov r7, r11, lsr #8 @ r7 = |00000000|00000000|00000000|rrrrrggg|
|
||||
@
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r7, [r0, #0x10] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r11, [r0, #0x10] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
#if LCD_WIDTH >= LCD_HEIGHT
|
||||
@ This element is zero - use r14 @
|
||||
@
|
||||
add r3, r3, r14 @ b = r3 + delta
|
||||
add r11, r11, r14, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r14, lsr #1 @ g = r7 + delta/2
|
||||
#else
|
||||
add r12, r14, #0x200 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
#endif
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
@
|
||||
and r11, r11, #0xf800 @ r11 = |00000000|00000000|rrrrrggg|gggbbbbb|
|
||||
and r7, r7, #0x7e00 @
|
||||
orr r11, r11, r7, lsr #4 @
|
||||
orr r11, r11, r3, lsr #10 @
|
||||
mov r7, r11, lsr #8 @ r7 = |00000000|00000000|00000000|rrrrrggg|
|
||||
@
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r7, [r0, #0x10] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r11, [r0, #0x10] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
#if LCD_WIDTH >= LCD_HEIGHT
|
||||
add r12, r14, #0x100 @
|
||||
#else
|
||||
add r12, r14, #0x300 @
|
||||
#endif
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
and r11, r11, #0xf800 @ r11 = |00000000|00000000|rrrrrggg|gggbbbbb|
|
||||
and r7, r7, #0x7e00 @
|
||||
orr r11, r11, r7, lsr #4 @
|
||||
orr r11, r11, r3, lsr #10 @
|
||||
mov r7, r11, lsr #8 @ r7 = |00000000|00000000|00000000|rrrrrggg|
|
||||
@
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r7, [r0, #0x10] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r11, [r0, #0x10] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
#if LCD_WIDTH >= LCD_HEIGHT
|
||||
add r12, r14, #0x300 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
#else
|
||||
@ This element is zero - use r14 @
|
||||
@
|
||||
add r3, r3, r14 @ b = r3 + delta
|
||||
add r11, r11, r14, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r14, lsr #1 @ g = r7 + delta/2
|
||||
#endif
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
and r11, r11, #0xf800 @ r11 = |00000000|00000000|rrrrrggg|gggbbbbb|
|
||||
and r7, r7, #0x7e00 @
|
||||
orr r11, r11, r7, lsr #4 @
|
||||
orr r11, r11, r3, lsr #10 @
|
||||
mov r7, r11, lsr #8 @ r7 = |00000000|00000000|00000000|rrrrrggg|
|
||||
@
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r7, [r0, #0x10] @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD1_BUSY_MASK @
|
||||
bne 20b @
|
||||
strb r11, [r0, #0x10] @
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r11 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
|
||||
|
|
@ -75,9 +75,6 @@ static void lcd_display_off(void);
|
|||
#define R_GATE_OUT_PERIOD_CTRL 0x71
|
||||
#define R_SOFTWARE_RESET 0x72
|
||||
|
||||
/* Display status */
|
||||
static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
|
||||
|
||||
/* wait for LCD */
|
||||
static inline void lcd_wait_write(void)
|
||||
{
|
||||
|
|
@ -407,85 +404,6 @@ void lcd_set_flip(bool yesno)
|
|||
lcd_write_reg(R_DRV_OUTPUT_CONTROL, flip ? 0x090c : 0x0a0c);
|
||||
}
|
||||
|
||||
void lcd_yuv_set_options(unsigned options)
|
||||
{
|
||||
lcd_yuv_options = options;
|
||||
}
|
||||
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD */
|
||||
void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride);
|
||||
void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride,
|
||||
int x_screen,
|
||||
int y_screen);
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
const unsigned char *yuv_src[3];
|
||||
const unsigned char *ysrc_max;
|
||||
int options;
|
||||
|
||||
if (!display_on)
|
||||
return;
|
||||
|
||||
width &= ~1;
|
||||
height &= ~1;
|
||||
|
||||
/* calculate the drawing region */
|
||||
lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x);
|
||||
|
||||
/* convert YUV coordinates to screen coordinates */
|
||||
y = LCD_WIDTH - 1 - y;
|
||||
|
||||
/* 2px strip: cursor moves left, then down in gram */
|
||||
/* BGR=1, MDT1-0=00, I/D1-0=10, AM=0 */
|
||||
lcd_write_reg(R_ENTRY_MODE, 0x1020);
|
||||
|
||||
yuv_src[0] = src[0] + src_y * stride + src_x;
|
||||
yuv_src[1] = src[1] + (src_y * stride >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
ysrc_max = yuv_src[0] + height * stride;
|
||||
|
||||
/* cache options setting */
|
||||
options = lcd_yuv_options;
|
||||
|
||||
do
|
||||
{
|
||||
/* max horiz << 8 | start horiz */
|
||||
lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (y << 8) | (y - 1));
|
||||
|
||||
/* position cursor (set AD0-AD15) */
|
||||
lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | y);
|
||||
|
||||
/* start drawing */
|
||||
lcd_send_command(R_WRITE_DATA_2_GRAM);
|
||||
|
||||
if (options & LCD_YUV_DITHER)
|
||||
{
|
||||
lcd_write_yuv420_lines_odither(yuv_src, width, stride,
|
||||
y, x);
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd_write_yuv420_lines(yuv_src, width, stride);
|
||||
}
|
||||
|
||||
y -= 2; /* move strip by "down" 2 px */
|
||||
yuv_src[0] += stride << 1;
|
||||
yuv_src[1] += stride >> 1;
|
||||
yuv_src[2] += stride >> 1;
|
||||
}
|
||||
while (yuv_src[0] < ysrc_max);
|
||||
|
||||
/* back to normal right, then down cursor in gram */
|
||||
/* BGR=1, MDT1-0=00, I/D1-0=11, AM=0 */
|
||||
lcd_write_reg(R_ENTRY_MODE, 0x1030);
|
||||
}
|
||||
|
||||
/* Update the display.
|
||||
This must be called after all other LCD functions that change the display. */
|
||||
void lcd_update(void)
|
||||
|
|
|
|||
|
|
@ -207,18 +207,3 @@ bool lcd_active()
|
|||
{
|
||||
return display_on;
|
||||
}
|
||||
|
||||
/* Blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
(void)src;
|
||||
(void)src_x;
|
||||
(void)src_y;
|
||||
(void)stride;
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)width;
|
||||
(void)height;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -268,18 +268,3 @@ bool lcd_active()
|
|||
{
|
||||
return display_on;
|
||||
}
|
||||
|
||||
/* Blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
(void)src;
|
||||
(void)src_x;
|
||||
(void)src_y;
|
||||
(void)stride;
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)width;
|
||||
(void)height;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,18 +231,3 @@ bool lcd_active()
|
|||
{
|
||||
return display_on;
|
||||
}
|
||||
|
||||
/* Blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
(void)src;
|
||||
(void)src_x;
|
||||
(void)src_y;
|
||||
(void)stride;
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)width;
|
||||
(void)height;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,18 +211,3 @@ bool lcd_active()
|
|||
{
|
||||
return display_on;
|
||||
}
|
||||
|
||||
/* Blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
(void)src;
|
||||
(void)src_x;
|
||||
(void)src_y;
|
||||
(void)stride;
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)width;
|
||||
(void)height;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -350,22 +350,3 @@ bool lcd_active()
|
|||
{
|
||||
return display_on;
|
||||
}
|
||||
|
||||
/* Blit a YUV bitmap directly to the LCD
|
||||
* provided by generic fallback in lcd-16bit-common.c
|
||||
*/
|
||||
#if 0
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
(void)src;
|
||||
(void)src_x;
|
||||
(void)src_y;
|
||||
(void)stride;
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)width;
|
||||
(void)height;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -253,18 +253,3 @@ bool lcd_active()
|
|||
{
|
||||
return display_on;
|
||||
}
|
||||
|
||||
/* Blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
(void)src;
|
||||
(void)src_x;
|
||||
(void)src_y;
|
||||
(void)stride;
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)width;
|
||||
(void)height;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,22 +178,3 @@ void lcd_set_gram_area(int x_start, int y_start,
|
|||
lcd_cmd(GRAM_WRITE);
|
||||
LCDC_CTRL &= ~RGB24B;
|
||||
}
|
||||
|
||||
/* Blit a YUV bitmap directly to the LCD
|
||||
* provided by generic fallback in lcd-16bit-common.c
|
||||
*/
|
||||
#if 0
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
(void)src;
|
||||
(void)src_x;
|
||||
(void)src_y;
|
||||
(void)stride;
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)width;
|
||||
(void)height;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -65,231 +65,3 @@ lcd_write_line: /* r2 = LCD_BASE */
|
|||
bgt .loop
|
||||
|
||||
ldmpc regs=r4-r6
|
||||
|
||||
/****************************************************************************
|
||||
* extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
* const unsigned LCD_BASE,
|
||||
* int width,
|
||||
* int stride);
|
||||
*
|
||||
* Conversion from Motion JPEG and MPEG Y'PbPr to RGB is:
|
||||
* |R| |1.164 0.000 1.596| |Y' - 16|
|
||||
* |G| = |1.164 -0.391 -0.813| |Pb - 128|
|
||||
* |B| |1.164 2.018 0.000| |Pr - 128|
|
||||
*
|
||||
* Scaled, normalized, rounded and tweaked to yield RGB 565:
|
||||
* |R| |74 0 101| |Y' - 16| >> 9
|
||||
* |G| = |74 -24 -51| |Cb - 128| >> 8
|
||||
* |B| |74 128 0| |Cr - 128| >> 9
|
||||
*
|
||||
* Converts two lines from YUV to RGB565 and writes to LCD at once. First loop
|
||||
* loads Cb/Cr, calculates the chroma offset and saves them to buffer. Within
|
||||
* the second loop these chroma offset are reloaded from buffer. Within each
|
||||
* loop two pixels are calculated and written to LCD.
|
||||
*/
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines
|
||||
.type lcd_write_yuv420_lines, %function
|
||||
lcd_write_yuv420_lines:
|
||||
/* r0 = src = yuv_src */
|
||||
/* r1 = dst = LCD_BASE */
|
||||
/* r2 = width */
|
||||
/* r3 = stride */
|
||||
stmfd sp!, { r4-r10, lr } /* save non-scratch */
|
||||
ldmia r0, { r9, r10, r12 } /* r9 = yuv_src[0] = Y'_p */
|
||||
/* r10 = yuv_src[1] = Cb_p */
|
||||
/* r12 = yuv_src[2] = Cr_p */
|
||||
add r3, r9, r3 /* r3 = &ysrc[stride] */
|
||||
add r4, r2, r2, asr #1 /* chroma buffer lenght = width/2 *3 */
|
||||
mov r4, r4, asl #2 /* use words for str/ldm possibility */
|
||||
add r4, r4, #19 /* plus room for 4 additional words, */
|
||||
bic r4, r4, #3 /* rounded up to multiples of 4 byte */
|
||||
sub sp, sp, r4 /* and allocate on stack */
|
||||
stmia sp, {r1-r4} /* LCD_BASE, width, &ysrc[stride], stack_alloc */
|
||||
|
||||
mov r7, r2 /* r7 = loop count */
|
||||
add r8, sp, #16 /* chroma buffer */
|
||||
add lr, r1, #0x40 /* LCD data port = LCD_BASE + 0x40 */
|
||||
|
||||
/* 1st loop start */
|
||||
10: /* loop start */
|
||||
|
||||
ldrb r0, [r10], #1 /* r0 = *usrc++ = *Cb_p++ */
|
||||
ldrb r1, [r12], #1 /* r1 = *vsrc++ = *Cr_p++ */
|
||||
|
||||
sub r0, r0, #128 /* r0 = Cb-128 */
|
||||
sub r1, r1, #128 /* r1 = Cr-128 */
|
||||
|
||||
add r2, r1, r1, asl #1 /* r2 = Cr*51 + Cb*24 */
|
||||
add r2, r2, r2, asl #4
|
||||
add r2, r2, r0, asl #3
|
||||
add r2, r2, r0, asl #4
|
||||
|
||||
add r4, r1, r1, asl #2 /* r1 = Cr*101 */
|
||||
add r4, r4, r1, asl #5
|
||||
add r1, r4, r1, asl #6
|
||||
|
||||
add r1, r1, #256 /* r1 = rv = (r1 + 256) >> 9 */
|
||||
mov r1, r1, asr #9
|
||||
rsb r2, r2, #128 /* r2 = guv = (-r2 + 128) >> 8 */
|
||||
mov r2, r2, asr #8
|
||||
add r0, r0, #2 /* r0 = bu = (Cb*128 + 256) >> 9 */
|
||||
mov r0, r0, asr #2
|
||||
stmia r8!, {r0-r2} /* store r0, r1 and r2 to chroma buffer */
|
||||
|
||||
/* 1st loop, first pixel */
|
||||
ldrb r5, [r9], #1 /* r5 = *ysrc++ = *Y'_p++ */
|
||||
sub r5, r5, #16 /* r5 = (Y'-16) * 74 */
|
||||
add r3, r5, r5, asl #2
|
||||
add r5, r3, r5, asl #5
|
||||
|
||||
add r6, r1, r5, asr #8 /* r6 = r = (Y >> 9) + rv */
|
||||
add r3, r2, r5, asr #7 /* r3 = g = (Y >> 8) + guv */
|
||||
add r4, r0, r5, asr #8 /* r4 = b = (Y >> 9) + bu */
|
||||
|
||||
orr r5, r6, r4 /* check if clamping is needed... */
|
||||
orr r5, r5, r3, asr #1 /* ...at all */
|
||||
cmp r5, #31
|
||||
bls 15f /* -> no clamp */
|
||||
cmp r6, #31 /* clamp r */
|
||||
mvnhi r6, r6, asr #31
|
||||
andhi r6, r6, #31
|
||||
cmp r3, #63 /* clamp g */
|
||||
mvnhi r3, r3, asr #31
|
||||
andhi r3, r3, #63
|
||||
cmp r4, #31 /* clamp b */
|
||||
mvnhi r4, r4, asr #31
|
||||
andhi r4, r4, #31
|
||||
15: /* no clamp */
|
||||
|
||||
/* calculate pixel_1 and save to r4 for later pixel packing */
|
||||
orr r4, r4, r3, lsl #5 /* pixel_1 = r<<11 | g<<5 | b */
|
||||
orr r4, r4, r6, lsl #11 /* r4 = pixel_1 */
|
||||
|
||||
/* 1st loop, second pixel */
|
||||
ldrb r5, [r9], #1 /* r5 = *ysrc++ = *Y'_p++ */
|
||||
sub r5, r5, #16 /* r5 = (Y'-16) * 74 */
|
||||
add r3, r5, r5, asl #2
|
||||
add r5, r3, r5, asl #5
|
||||
|
||||
add r6, r1, r5, asr #8 /* r6 = r = (Y >> 9) + rv */
|
||||
add r3, r2, r5, asr #7 /* r3 = g = (Y >> 8) + guv */
|
||||
add r5, r0, r5, asr #8 /* r5 = b = (Y >> 9) + bu */
|
||||
|
||||
orr r0, r6, r5 /* check if clamping is needed... */
|
||||
orr r0, r0, r3, asr #1 /* ...at all */
|
||||
cmp r0, #31
|
||||
bls 15f /* -> no clamp */
|
||||
cmp r6, #31 /* clamp r */
|
||||
mvnhi r6, r6, asr #31
|
||||
andhi r6, r6, #31
|
||||
cmp r3, #63 /* clamp g */
|
||||
mvnhi r3, r3, asr #31
|
||||
andhi r3, r3, #63
|
||||
cmp r5, #31 /* clamp b */
|
||||
mvnhi r5, r5, asr #31
|
||||
andhi r5, r5, #31
|
||||
15: /* no clamp */
|
||||
|
||||
/* calculate pixel_2 and pack with pixel_1 before writing */
|
||||
orr r5, r5, r3, lsl #5 /* pixel_2 = r<<11 | g<<5 | b */
|
||||
orr r5, r5, r6, lsl #11 /* r5 = pixel_2 */
|
||||
#ifdef FORCE_FIFO_WAIT
|
||||
/* wait for FIFO half full */
|
||||
.fifo_wait1:
|
||||
ldr r3, [lr, #-0x24] /* while (LCD_STATUS & 0x08); */
|
||||
tst r3, #0x8
|
||||
bgt .fifo_wait1
|
||||
#endif
|
||||
stmia lr, {r4,r5} /* write pixel_1 and pixel_2 */
|
||||
|
||||
subs r7, r7, #2 /* check for loop end */
|
||||
bgt 10b /* back to beginning */
|
||||
/* 1st loop end */
|
||||
|
||||
/* Reload several registers for pointer rewinding for next loop */
|
||||
add r8, sp, #16 /* chroma buffer */
|
||||
ldmia sp, { r1, r7, r9} /* r1 = LCD_BASE */
|
||||
/* r7 = loop count */
|
||||
/* r9 = &ysrc[stride] */
|
||||
|
||||
/* 2nd loop start */
|
||||
20: /* loop start */
|
||||
/* restore r0 (bu), r1 (rv) and r2 (guv) from chroma buffer */
|
||||
ldmia r8!, {r0-r2}
|
||||
|
||||
/* 2nd loop, first pixel */
|
||||
ldrb r5, [r9], #1 /* r5 = *ysrc++ = *Y'_p++ */
|
||||
sub r5, r5, #16 /* r5 = (Y'-16) * 74 */
|
||||
add r3, r5, r5, asl #2
|
||||
add r5, r3, r5, asl #5
|
||||
|
||||
add r6, r1, r5, asr #8 /* r6 = r = (Y >> 9) + rv */
|
||||
add r3, r2, r5, asr #7 /* r3 = g = (Y >> 8) + guv */
|
||||
add r4, r0, r5, asr #8 /* r4 = b = (Y >> 9) + bu */
|
||||
|
||||
orr r5, r6, r4 /* check if clamping is needed... */
|
||||
orr r5, r5, r3, asr #1 /* ...at all */
|
||||
cmp r5, #31
|
||||
bls 15f /* -> no clamp */
|
||||
cmp r6, #31 /* clamp r */
|
||||
mvnhi r6, r6, asr #31
|
||||
andhi r6, r6, #31
|
||||
cmp r3, #63 /* clamp g */
|
||||
mvnhi r3, r3, asr #31
|
||||
andhi r3, r3, #63
|
||||
cmp r4, #31 /* clamp b */
|
||||
mvnhi r4, r4, asr #31
|
||||
andhi r4, r4, #31
|
||||
15: /* no clamp */
|
||||
/* calculate pixel_1 and save to r4 for later pixel packing */
|
||||
orr r4, r4, r3, lsl #5 /* pixel_1 = r<<11 | g<<5 | b */
|
||||
orr r4, r4, r6, lsl #11 /* r4 = pixel_1 */
|
||||
|
||||
/* 2nd loop, second pixel */
|
||||
ldrb r5, [r9], #1 /* r5 = *ysrc++ = *Y'_p++ */
|
||||
sub r5, r5, #16 /* r5 = (Y'-16) * 74 */
|
||||
add r3, r5, r5, asl #2
|
||||
add r5, r3, r5, asl #5
|
||||
|
||||
add r6, r1, r5, asr #8 /* r6 = r = (Y >> 9) + rv */
|
||||
add r3, r2, r5, asr #7 /* r3 = g = (Y >> 8) + guv */
|
||||
add r5, r0, r5, asr #8 /* r5 = b = (Y >> 9) + bu */
|
||||
|
||||
orr r0, r6, r5 /* check if clamping is needed... */
|
||||
orr r0, r0, r3, asr #1 /* ...at all */
|
||||
cmp r0, #31
|
||||
bls 15f /* -> no clamp */
|
||||
cmp r6, #31 /* clamp r */
|
||||
mvnhi r6, r6, asr #31
|
||||
andhi r6, r6, #31
|
||||
cmp r3, #63 /* clamp g */
|
||||
mvnhi r3, r3, asr #31
|
||||
andhi r3, r3, #63
|
||||
cmp r5, #31 /* clamp b */
|
||||
mvnhi r5, r5, asr #31
|
||||
andhi r5, r5, #31
|
||||
15: /* no clamp */
|
||||
|
||||
/* calculate pixel_2 and pack with pixel_1 before writing */
|
||||
orr r5, r5, r3, lsl #5 /* pixel_2 = r<<11 | g<<5 | b */
|
||||
orr r5, r5, r6, lsl #11 /* r5 = pixel_2 */
|
||||
#ifdef FORCE_FIFO_WAIT
|
||||
/* wait for FIFO half full */
|
||||
.fifo_wait2:
|
||||
ldr r3, [lr, #-0x24] /* while (LCD_STATUS & 0x08); */
|
||||
tst r3, #0x8
|
||||
bgt .fifo_wait2
|
||||
#endif
|
||||
stmia lr, {r4,r5} /* write pixel_1 and pixel_2 */
|
||||
|
||||
subs r7, r7, #2 /* check for loop end */
|
||||
bgt 20b /* back to beginning */
|
||||
/* 2nd loop end */
|
||||
|
||||
ldr r3, [sp, #12]
|
||||
add sp, sp, r3 /* deallocate buffer */
|
||||
ldmpc regs=r4-r10 /* restore registers */
|
||||
|
||||
.ltorg
|
||||
.size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
|
||||
|
|
|
|||
|
|
@ -406,36 +406,3 @@ void lcd_update_rect(int x, int y, int width, int height)
|
|||
} while (--height > 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */
|
||||
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
const unsigned int lcd_baseadress,
|
||||
int width,
|
||||
int stride);
|
||||
|
||||
/* Blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
unsigned int z;
|
||||
unsigned char const * yuv_src[3];
|
||||
|
||||
width = (width + 1) & ~1; /* ensure width is even */
|
||||
|
||||
lcd_setup_drawing_region(x, y, width, height);
|
||||
|
||||
z = stride * src_y;
|
||||
yuv_src[0] = src[0] + z + src_x;
|
||||
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
|
||||
height >>= 1;
|
||||
|
||||
do {
|
||||
lcd_write_yuv420_lines(yuv_src, LCD_BASE, width, stride);
|
||||
yuv_src[0] += stride << 1;
|
||||
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
|
||||
yuv_src[2] += stride >> 1;
|
||||
} while (--height > 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,11 +311,3 @@ void lcd_update_rect(int x, int y, int width, int height)
|
|||
{
|
||||
lcd_update();
|
||||
}
|
||||
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
/* stub */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -476,19 +476,3 @@ void lcd_update(void)
|
|||
{
|
||||
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
|
||||
}
|
||||
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
(void)src;
|
||||
(void)src_x;
|
||||
(void)src_y;
|
||||
(void)stride;
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)width;
|
||||
(void)height;
|
||||
/* TODO: not implemented yet */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -530,49 +530,3 @@ void lcd_update_rect(int x, int y, int width, int height)
|
|||
|
||||
displaylcd_dma(pixels);
|
||||
}
|
||||
|
||||
/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */
|
||||
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
uint16_t* outbuf,
|
||||
int width,
|
||||
int stride);
|
||||
|
||||
/* Blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height) ICODE_ATTR;
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
unsigned int z;
|
||||
unsigned char const * yuv_src[3];
|
||||
|
||||
#ifdef HAVE_LCD_SLEEP
|
||||
if (!lcd_active()) return;
|
||||
#endif
|
||||
|
||||
width = (width + 1) & ~1; /* ensure width is even */
|
||||
|
||||
int pixels = width * height;
|
||||
uint16_t* out = lcd_dblbuf[0];
|
||||
|
||||
z = stride * src_y;
|
||||
yuv_src[0] = src[0] + z + src_x;
|
||||
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
|
||||
displaylcd_setup(x, y, width, height);
|
||||
|
||||
height >>= 1;
|
||||
|
||||
do {
|
||||
lcd_write_yuv420_lines(yuv_src, out, width, stride);
|
||||
yuv_src[0] += stride << 1;
|
||||
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
|
||||
yuv_src[2] += stride >> 1;
|
||||
out += width << 1;
|
||||
} while (--height);
|
||||
|
||||
displaylcd_dma(pixels);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,550 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
* Heavily based on lcd-as-memframe.c by Michael Sevakis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Scaled, normalized, rounded and tweaked to yield RGB 565:
|
||||
* |R| |74 0 101| |Y' - 16| >> 9
|
||||
* |G| = |74 -24 -51| |Cb - 128| >> 8
|
||||
* |B| |74 128 0| |Cr - 128| >> 9
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines
|
||||
.type lcd_write_yuv420_lines, %function
|
||||
lcd_write_yuv420_lines:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
stmfd sp!, { r4-r10, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@ r0 = scratch
|
||||
sub r2, r2, #1 @
|
||||
mov r3, #0x70000000 @
|
||||
orr r3, r3, #0x3000 @ r3 = LCD1_BASE
|
||||
10: @ loop line @
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
|
||||
add r7, r12, r7, asl #5 @ by one less when adding - same for all
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
|
||||
add r10, r10, r10, asl #4 @
|
||||
add r10, r10, r8, asl #3 @
|
||||
add r10, r10, r8, asl #4 @
|
||||
@
|
||||
add lr, r9, r9, asl #2 @ r9 = Cr*101
|
||||
add lr, lr, r9, asl #5 @
|
||||
add r9, lr, r9, asl #6 @
|
||||
@
|
||||
add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
|
||||
mov r8, r8, asr #2 @
|
||||
add r9, r9, #256 @ r9 = rv = (r9 + 256) >> 9
|
||||
mov r9, r9, asr #9 @
|
||||
rsb r10, r10, #128 @ r10 = guv = (-r10 + 128) >> 8
|
||||
mov r10, r10, asr #8 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
|
||||
add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r0, lr @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r0, #31 @ clamp b
|
||||
mvnhi r0, r0, asr #31 @
|
||||
andhi r0, r0, #31 @
|
||||
cmp lr, #31 @ clamp r
|
||||
mvnhi lr, lr, asr #31 @
|
||||
andhi lr, lr, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
mov lr, lr, lsl #3 @
|
||||
orr lr, lr, r7, lsr #3 @ lr = (r << 3) | (g >> 3)
|
||||
orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str lr, [r3, #0x10] @ send MSB
|
||||
1: @busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
|
||||
add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r0, lr @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r0, #31 @ clamp b
|
||||
mvnhi r0, r0, asr #31 @
|
||||
andhi r0, r0, #31 @
|
||||
cmp lr, #31 @ clamp r
|
||||
mvnhi lr, lr, asr #31 @
|
||||
andhi lr, lr, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
@
|
||||
mov lr, lr, lsl #3 @
|
||||
orr lr, lr, r7, lsr #3 @ lr = (r << 3) | (g >> 3)
|
||||
orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str lr, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
|
||||
add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r0, lr @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r0, #31 @ clamp b
|
||||
mvnhi r0, r0, asr #31 @
|
||||
andhi r0, r0, #31 @
|
||||
cmp lr, #31 @ clamp r
|
||||
mvnhi lr, lr, asr #31 @
|
||||
andhi lr, lr, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
@
|
||||
mov lr, lr, lsl #3 @
|
||||
orr lr, lr, r7, lsr #3 @ lr = (r << 3) | (g >> 3)
|
||||
orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str lr, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
|
||||
add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r0, lr @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r0, #31 @ clamp b
|
||||
mvnhi r0, r0, asr #31 @
|
||||
andhi r0, r0, #31 @
|
||||
cmp lr, #31 @ clamp r
|
||||
mvnhi lr, lr, asr #31 @
|
||||
andhi lr, lr, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
mov lr, lr, lsl #3 @
|
||||
orr lr, lr, r7, lsr #3 @ lr = (r << 3) | (g >> 3)
|
||||
orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str lr, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r10 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride,
|
||||
* int x_screen,
|
||||
* int y_screen);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Red scaled at twice g & b but at same precision to place it in correct
|
||||
* bit position after multiply and leave instruction count lower.
|
||||
* |R| |258 0 408| |Y' - 16|
|
||||
* |G| = |149 -49 -104| |Cb - 128|
|
||||
* |B| |149 258 0| |Cr - 128|
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*
|
||||
* Kernel pattern (raw|rotated|use order):
|
||||
* 5 3 4 2 2 6 3 7 row0 row2 > down
|
||||
* 1 7 0 6 | 4 0 5 1 | 2 4 6 0 3 5 7 1 col0 left
|
||||
* 4 2 5 3 | 3 7 2 6 | 3 5 7 1 2 4 6 0 col2 \/
|
||||
* 0 6 1 7 5 1 4 0
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines_odither
|
||||
.type lcd_write_yuv420_lines_odither, %function
|
||||
lcd_write_yuv420_lines_odither:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
@ r3 = x_screen
|
||||
@ [sp] = y_screen
|
||||
stmfd sp!, { r4-r11, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@
|
||||
sub r2, r2, #1 @
|
||||
ldr r14, [sp, #36] @ Line up pattern and kernel quadrant
|
||||
eor r14, r14, r3 @
|
||||
and r14, r14, #0x2 @
|
||||
mov r14, r14, lsl #6 @ 0x00 or 0x80
|
||||
mov r3, #0x70000000 @
|
||||
orr r3, r3, #0x3000 @ r3 = LCD1_BASE
|
||||
10: @ loop line @
|
||||
@
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
eor r14, r14, #0x80 @ flip pattern quadrant
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
|
||||
add r10, r10, r8, asl #5 @
|
||||
add r10, r10, r9, asl #3 @
|
||||
add r10, r10, r9, asl #5 @
|
||||
add r10, r10, r9, asl #6 @
|
||||
@
|
||||
mov r8, r8, asl #1 @ r8 = bu = Cb*258
|
||||
add r8, r8, r8, asl #7 @
|
||||
@
|
||||
add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
|
||||
add r9, r9, r9, asl #4 @
|
||||
mov r9, r9, asl #3 @
|
||||
@
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7 @ r0 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
|
||||
add r0, r12, r0, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x100 @
|
||||
@
|
||||
add r0, r0, r12 @ b = r0 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r0, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r0, asr #15 @ clamp b
|
||||
mvnne r0, r12, lsr #15 @
|
||||
andne r0, r0, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
mov r11, r11, lsr #8
|
||||
and r7, r7, #0x7e00
|
||||
orr r11, r11, r7, lsr #12
|
||||
mov r7, r7, lsr#4
|
||||
orr r0, r7, r0, lsr #10
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r11, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7 @ r0 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
|
||||
add r0, r12, r0, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x200 @
|
||||
@
|
||||
add r0, r0, r12 @ b = r0 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r0, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r0, asr #15 @ clamp b
|
||||
mvnne r0, r12, lsr #15 @
|
||||
andne r0, r0, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
mov r11, r11, lsr #8
|
||||
and r7, r7, #0x7e00
|
||||
orr r11, r11, r7, lsr #12
|
||||
mov r7, r7, lsr#4
|
||||
orr r0, r7, r0, lsr #10
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r11, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7 @ r0 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
|
||||
add r0, r12, r0, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x300 @
|
||||
@
|
||||
add r0, r0, r12 @ b = r0 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r0, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r0, asr #15 @ clamp b
|
||||
mvnne r0, r12, lsr #15 @
|
||||
andne r0, r0, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
mov r11, r11, lsr #8
|
||||
and r7, r7, #0x7e00
|
||||
orr r11, r11, r7, lsr #12
|
||||
mov r7, r7, lsr#4
|
||||
orr r0, r7, r0, lsr #10
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r11, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7 @ r0 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
|
||||
add r0, r12, r0, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
@ This element is zero - use r14 @
|
||||
@
|
||||
add r0, r0, r14 @ b = r0 + delta
|
||||
add r11, r11, r14, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r14, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r0, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r0, asr #15 @ clamp b
|
||||
mvnne r0, r12, lsr #15 @
|
||||
andne r0, r0, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
mov r11, r11, lsr #8
|
||||
and r7, r7, #0x7e00
|
||||
orr r11, r11, r7, lsr #12
|
||||
mov r7, r7, lsr#4
|
||||
orr r0, r7, r0, lsr #10
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r11, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r11 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
|
||||
|
|
@ -30,8 +30,6 @@
|
|||
#endif
|
||||
|
||||
/* Display status */
|
||||
static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
|
||||
|
||||
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
|
||||
static bool is_lcd_enabled = true;
|
||||
#endif
|
||||
|
|
@ -291,78 +289,6 @@ void lcd_set_flip(bool yesno)
|
|||
|
||||
/*** update functions ***/
|
||||
|
||||
void lcd_yuv_set_options(unsigned options)
|
||||
{
|
||||
lcd_yuv_options = options;
|
||||
}
|
||||
|
||||
/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
|
||||
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride);
|
||||
extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride,
|
||||
int x_screen, /* To align dither pattern */
|
||||
int y_screen);
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
unsigned char const * yuv_src[3];
|
||||
off_t z;
|
||||
|
||||
/* Sorry, but width and height must be >= 2 or else */
|
||||
width &= ~1;
|
||||
height >>= 1;
|
||||
|
||||
z = stride*src_y;
|
||||
yuv_src[0] = src[0] + z + src_x;
|
||||
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
|
||||
lcd_send_command(R_ENTRY_MODE);
|
||||
lcd_send_command(0x03);
|
||||
|
||||
lcd_send_command(R_Y_ADDR_AREA);
|
||||
lcd_send_command(x + 4);
|
||||
lcd_send_command(x + width - 1 + 4);
|
||||
|
||||
if (lcd_yuv_options & LCD_YUV_DITHER)
|
||||
{
|
||||
do
|
||||
{
|
||||
lcd_send_command(R_X_ADDR_AREA);
|
||||
lcd_send_command(y);
|
||||
lcd_send_command(y + 1);
|
||||
|
||||
lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y);
|
||||
yuv_src[0] += stride << 1; /* Skip down two luma lines */
|
||||
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
|
||||
yuv_src[2] += stride >> 1;
|
||||
y += 2;
|
||||
}
|
||||
while (--height > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
lcd_send_command(R_X_ADDR_AREA);
|
||||
lcd_send_command(y);
|
||||
lcd_send_command(y + 1);
|
||||
|
||||
lcd_write_yuv420_lines(yuv_src, width, stride);
|
||||
yuv_src[0] += stride << 1; /* Skip down two luma lines */
|
||||
yuv_src[1] += stride >> 1; /* Skip down one chroma line */
|
||||
yuv_src[2] += stride >> 1;
|
||||
y += 2;
|
||||
}
|
||||
while (--height > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the display.
|
||||
This must be called after all other LCD functions that change the display. */
|
||||
void lcd_update(void)
|
||||
|
|
|
|||
|
|
@ -1,538 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007-2008 by Michael Sevakis
|
||||
*
|
||||
* H10 20GB LCD assembly routines
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Scaled, normalized, rounded and tweaked to yield RGB 565:
|
||||
* |R| |74 0 101| |Y' - 16| >> 9
|
||||
* |G| = |74 -24 -51| |Cb - 128| >> 8
|
||||
* |B| |74 128 0| |Cr - 128| >> 9
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines
|
||||
.type lcd_write_yuv420_lines, %function
|
||||
lcd_write_yuv420_lines:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
stmfd sp!, { r4-r11, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@
|
||||
mov r0, #0x7000000c @ r0 = &LCD2_PORT = 0x70008a0c
|
||||
add r0, r0, #0x8a00 @
|
||||
mov r14, #LCD2_DATA_MASK @
|
||||
@
|
||||
sub r2, r2, #1 @ Adjust stride because of increment
|
||||
10: @ loop line @
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
|
||||
add r7, r12, r7, asl #5 @ by one less when adding - same for all
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
|
||||
add r10, r10, r10, asl #4 @
|
||||
add r10, r10, r8, asl #3 @
|
||||
add r10, r10, r8, asl #4 @
|
||||
@
|
||||
add r11, r9, r9, asl #2 @ r9 = Cr*101
|
||||
add r11, r11, r9, asl #5 @
|
||||
add r9, r11, r9, asl #6 @
|
||||
@
|
||||
add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
|
||||
mov r8, r8, asr #2 @
|
||||
add r9, r9, #256 @ r9 = rv = (r8 + 256) >> 9
|
||||
mov r9, r9, asr #9 @
|
||||
rsb r10, r10, #128 @ r10 = guv = (-r9 + 128) >> 8
|
||||
mov r10, r10, asr #8 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
|
||||
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
|
||||
@
|
||||
orr r7, r14, r3, lsr #8 @ store pixel
|
||||
orr r11, r14, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
@
|
||||
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
|
||||
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
|
||||
@
|
||||
orr r7, r14, r3, lsr #8 @ store pixel
|
||||
orr r11, r14, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
orr r3, r3, r7, lsl #5 @ r3 = b | (g << 5)
|
||||
orr r3, r3, r11, lsl #11 @ r3 |= (r << 11)
|
||||
@
|
||||
orr r7, r14, r3, lsr #8 @ store pixel
|
||||
orr r11, r14, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
|
||||
add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r3, r11 @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r3, #31 @ clamp b
|
||||
mvnhi r3, r3, asr #31 @
|
||||
andhi r3, r3, #31 @
|
||||
cmp r11, #31 @ clamp r
|
||||
mvnhi r11, r11, asr #31 @
|
||||
andhi r11, r11, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
|
||||
orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
|
||||
@
|
||||
orr r7, r14, r3, lsr #8 @ store pixel
|
||||
orr r11, r14, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r11 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride,
|
||||
* int x_screen,
|
||||
* int y_screen);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Red scaled at twice g & b but at same precision to place it in correct
|
||||
* bit position after multiply and leave instruction count lower.
|
||||
* |R| |258 0 408| |Y' - 16|
|
||||
* |G| = |149 -49 -104| |Cb - 128|
|
||||
* |B| |149 258 0| |Cr - 128|
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*
|
||||
* Kernel pattern (raw|use order):
|
||||
* 5 3 4 2 row0 row2 > down
|
||||
* 1 7 0 6 | 5 1 3 7 4 0 2 6 col0 left
|
||||
* 4 2 5 3 | 4 0 2 6 5 1 3 7 col2 \/
|
||||
* 0 6 1 7
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines_odither
|
||||
.type lcd_write_yuv420_lines_odither, %function
|
||||
lcd_write_yuv420_lines_odither:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
@ r3 = x_screen
|
||||
@ [sp] = y_screen
|
||||
stmfd sp!, { r4-r11, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@
|
||||
ldr r0, [sp, #36] @ Line up pattern and kernel quadrant
|
||||
eor r14, r3, r0 @
|
||||
and r14, r14, #0x2 @
|
||||
mov r14, r14, lsl #6 @ 0x00 or 0x80
|
||||
@
|
||||
mov r0, #0x7000000c @ r0 = &LCD2_PORT = 0x70008a0c
|
||||
add r0, r0, #0x8a00 @
|
||||
@
|
||||
sub r2, r2, #1 @ Adjust stride because of increment
|
||||
10: @ loop line @
|
||||
@
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
eor r14, r14, #0x80 @ flip pattern quadrant
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
|
||||
add r10, r10, r8, asl #5 @
|
||||
add r10, r10, r9, asl #3 @
|
||||
add r10, r10, r9, asl #5 @
|
||||
add r10, r10, r9, asl #6 @
|
||||
@
|
||||
mov r8, r8, asl #1 @ r8 = bu = Cb*258
|
||||
add r8, r8, r8, asl #7 @
|
||||
@
|
||||
add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
|
||||
add r9, r9, r9, asl #4 @
|
||||
mov r9, r9, asl #3 @
|
||||
@
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x200 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
mov r11, #LCD2_DATA_MASK @ store pixel
|
||||
orr r7, r11, r3, lsr #8 @
|
||||
orr r11, r11, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
@ This element is zero - use r14 @
|
||||
@
|
||||
add r3, r3, r14 @ b = r3 + delta
|
||||
add r11, r11, r14, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r14, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
mov r11, #LCD2_DATA_MASK @ store pixel
|
||||
orr r7, r11, r3, lsr #8 @
|
||||
orr r11, r11, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x100 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
mov r11, #LCD2_DATA_MASK @ store pixel
|
||||
orr r7, r11, r3, lsr #8 @
|
||||
orr r11, r11, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r3, r8, r7 @ r3 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
|
||||
add r3, r12, r3, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x300 @
|
||||
@
|
||||
add r3, r3, r12 @ b = r3 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r3, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r3, asr #15 @ clamp b
|
||||
mvnne r3, r12, lsr #15 @
|
||||
andne r3, r3, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
|
||||
orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
|
||||
orr r3, r11, r3, lsr #10 @ (b >> 10)
|
||||
@
|
||||
mov r11, #LCD2_DATA_MASK @ store pixel
|
||||
orr r7, r11, r3, lsr #8 @
|
||||
orr r11, r11, r3 @
|
||||
20: @
|
||||
ldr r3, [r0] @
|
||||
tst r3, #LCD2_BUSY_MASK @
|
||||
bne 20b @
|
||||
str r7, [r0] @
|
||||
str r11, [r0] @
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r11 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
|
||||
|
|
@ -37,8 +37,6 @@ static unsigned short disp_control_rev;
|
|||
/* Contrast setting << 8 */
|
||||
static int lcd_contrast;
|
||||
|
||||
static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
|
||||
|
||||
/* Forward declarations */
|
||||
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
|
||||
static void lcd_display_off(void);
|
||||
|
|
@ -510,98 +508,6 @@ bool lcd_active(void)
|
|||
|
||||
/*** update functions ***/
|
||||
|
||||
void lcd_yuv_set_options(unsigned options)
|
||||
{
|
||||
lcd_yuv_options = options;
|
||||
}
|
||||
|
||||
/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
|
||||
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride);
|
||||
extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
int width,
|
||||
int stride,
|
||||
int x_screen, /* To align dither pattern */
|
||||
int y_screen);
|
||||
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
const unsigned char *yuv_src[3];
|
||||
const unsigned char *ysrc_max;
|
||||
int y0;
|
||||
int options;
|
||||
|
||||
/* NOT MODIFIED FOR THE YH-925 */
|
||||
|
||||
if (!display_on)
|
||||
return;
|
||||
|
||||
width &= ~1;
|
||||
height &= ~1;
|
||||
|
||||
x += x_offset;
|
||||
|
||||
/* calculate the drawing region */
|
||||
|
||||
/* The 20GB LCD is actually 128x160 but rotated 90 degrees so the origin
|
||||
* is actually the bottom left and horizontal and vertical are swapped.
|
||||
* Rockbox expects the origin to be the top left so we need to use
|
||||
* 127 - y instead of just y */
|
||||
|
||||
/* max vert << 8 | start vert */
|
||||
lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x);
|
||||
|
||||
y0 = LCD_HEIGHT - 1 - y + y_offset;
|
||||
|
||||
/* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=0, LG2-0=000 */
|
||||
lcd_write_reg(R_ENTRY_MODE, 0x1020);
|
||||
|
||||
yuv_src[0] = src[0] + src_y * stride + src_x;
|
||||
yuv_src[1] = src[1] + (src_y * stride >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
ysrc_max = yuv_src[0] + height * stride;
|
||||
|
||||
options = lcd_yuv_options;
|
||||
|
||||
do
|
||||
{
|
||||
/* max horiz << 8 | start horiz */
|
||||
lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (y0 << 8) | (y0 - 1));
|
||||
|
||||
/* position cursor (set AD0-AD15) */
|
||||
/* start vert << 8 | start horiz */
|
||||
lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | y0);
|
||||
|
||||
/* start drawing */
|
||||
lcd_send_cmd(R_WRITE_DATA_2_GRAM);
|
||||
|
||||
if (options & LCD_YUV_DITHER)
|
||||
{
|
||||
lcd_write_yuv420_lines_odither(yuv_src, width, stride,
|
||||
x, y);
|
||||
y -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd_write_yuv420_lines(yuv_src, width, stride);
|
||||
}
|
||||
|
||||
y0 -= 2;
|
||||
yuv_src[0] += stride << 1;
|
||||
yuv_src[1] += stride >> 1;
|
||||
yuv_src[2] += stride >> 1;
|
||||
}
|
||||
while (yuv_src[0] < ysrc_max);
|
||||
|
||||
/* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=1, LG2-0=000 */
|
||||
lcd_write_reg(R_ENTRY_MODE, 0x1028);
|
||||
}
|
||||
|
||||
|
||||
/* Update a fraction of the display. */
|
||||
void lcd_update_rect(int x0, int y0, int width, int height)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,550 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
* Heavily based on lcd-as-memframe.c by Michael Sevakis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Scaled, normalized, rounded and tweaked to yield RGB 565:
|
||||
* |R| |74 0 101| |Y' - 16| >> 9
|
||||
* |G| = |74 -24 -51| |Cb - 128| >> 8
|
||||
* |B| |74 128 0| |Cr - 128| >> 9
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines
|
||||
.type lcd_write_yuv420_lines, %function
|
||||
lcd_write_yuv420_lines:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
stmfd sp!, { r4-r10, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@ r0 = scratch
|
||||
sub r2, r2, #1 @
|
||||
mov r3, #0x70000000 @
|
||||
orr r3, r3, #0x3000 @ r3 = LCD1_BASE
|
||||
10: @ loop line @
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
|
||||
add r7, r12, r7, asl #5 @ by one less when adding - same for all
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
|
||||
add r10, r10, r10, asl #4 @
|
||||
add r10, r10, r8, asl #3 @
|
||||
add r10, r10, r8, asl #4 @
|
||||
@
|
||||
add lr, r9, r9, asl #2 @ r9 = Cr*101
|
||||
add lr, lr, r9, asl #5 @
|
||||
add r9, lr, r9, asl #6 @
|
||||
@
|
||||
add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
|
||||
mov r8, r8, asr #2 @
|
||||
add r9, r9, #256 @ r9 = rv = (r9 + 256) >> 9
|
||||
mov r9, r9, asr #9 @
|
||||
rsb r10, r10, #128 @ r10 = guv = (-r10 + 128) >> 8
|
||||
mov r10, r10, asr #8 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
|
||||
add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r0, lr @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r0, #31 @ clamp b
|
||||
mvnhi r0, r0, asr #31 @
|
||||
andhi r0, r0, #31 @
|
||||
cmp lr, #31 @ clamp r
|
||||
mvnhi lr, lr, asr #31 @
|
||||
andhi lr, lr, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
mov lr, lr, lsl #3 @
|
||||
orr lr, lr, r7, lsr #3 @ lr = (r << 3) | (g >> 3)
|
||||
orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str lr, [r3, #0x10] @ send MSB
|
||||
1: @busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
|
||||
add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r0, lr @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r0, #31 @ clamp b
|
||||
mvnhi r0, r0, asr #31 @
|
||||
andhi r0, r0, #31 @
|
||||
cmp lr, #31 @ clamp r
|
||||
mvnhi lr, lr, asr #31 @
|
||||
andhi lr, lr, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
@
|
||||
mov lr, lr, lsl #3 @
|
||||
orr lr, lr, r7, lsr #3 @ lr = (r << 3) | (g >> 3)
|
||||
orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str lr, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
|
||||
add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r0, lr @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r0, #31 @ clamp b
|
||||
mvnhi r0, r0, asr #31 @
|
||||
andhi r0, r0, #31 @
|
||||
cmp lr, #31 @ clamp r
|
||||
mvnhi lr, lr, asr #31 @
|
||||
andhi lr, lr, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
@
|
||||
mov lr, lr, lsl #3 @
|
||||
orr lr, lr, r7, lsr #3 @ lr = (r << 3) | (g >> 3)
|
||||
orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str lr, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r7, r12, r7, asl #5 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
|
||||
add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
|
||||
add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
|
||||
@
|
||||
orr r12, r0, lr @ check if clamping is needed...
|
||||
orr r12, r12, r7, asr #1 @ ...at all
|
||||
cmp r12, #31 @
|
||||
bls 15f @ no clamp @
|
||||
cmp r0, #31 @ clamp b
|
||||
mvnhi r0, r0, asr #31 @
|
||||
andhi r0, r0, #31 @
|
||||
cmp lr, #31 @ clamp r
|
||||
mvnhi lr, lr, asr #31 @
|
||||
andhi lr, lr, #31 @
|
||||
cmp r7, #63 @ clamp g
|
||||
mvnhi r7, r7, asr #31 @
|
||||
andhi r7, r7, #63 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
mov lr, lr, lsl #3 @
|
||||
orr lr, lr, r7, lsr #3 @ lr = (r << 3) | (g >> 3)
|
||||
orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str lr, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
@
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r10 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
|
||||
|
||||
/****************************************************************************
|
||||
* void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
|
||||
* int width,
|
||||
* int stride,
|
||||
* int x_screen,
|
||||
* int y_screen);
|
||||
*
|
||||
* |R| |1.000000 -0.000001 1.402000| |Y'|
|
||||
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
|
||||
* |B| |1.000000 1.772000 0.000000| |Pr|
|
||||
* Red scaled at twice g & b but at same precision to place it in correct
|
||||
* bit position after multiply and leave instruction count lower.
|
||||
* |R| |258 0 408| |Y' - 16|
|
||||
* |G| = |149 -49 -104| |Cb - 128|
|
||||
* |B| |149 258 0| |Cr - 128|
|
||||
*
|
||||
* Write four RGB565 pixels in the following order on each loop:
|
||||
* 1 3 + > down
|
||||
* 2 4 \/ left
|
||||
*
|
||||
* Kernel pattern (raw|rotated|use order):
|
||||
* 5 3 4 2 2 6 3 7 row0 row2 > down
|
||||
* 1 7 0 6 | 4 0 5 1 | 2 4 6 0 3 5 7 1 col0 left
|
||||
* 4 2 5 3 | 3 7 2 6 | 3 5 7 1 2 4 6 0 col2 \/
|
||||
* 0 6 1 7 5 1 4 0
|
||||
*/
|
||||
.section .icode, "ax", %progbits
|
||||
.align 2
|
||||
.global lcd_write_yuv420_lines_odither
|
||||
.type lcd_write_yuv420_lines_odither, %function
|
||||
lcd_write_yuv420_lines_odither:
|
||||
@ r0 = yuv_src
|
||||
@ r1 = width
|
||||
@ r2 = stride
|
||||
@ r3 = x_screen
|
||||
@ [sp] = y_screen
|
||||
stmfd sp!, { r4-r11, lr } @ save non-scratch
|
||||
ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
|
||||
@ r5 = yuv_src[1] = Cb_p
|
||||
@ r6 = yuv_src[2] = Cr_p
|
||||
@
|
||||
sub r2, r2, #1 @
|
||||
ldr r14, [sp, #36] @ Line up pattern and kernel quadrant
|
||||
eor r14, r14, r3 @
|
||||
and r14, r14, #0x2 @
|
||||
mov r14, r14, lsl #6 @ 0x00 or 0x80
|
||||
mov r3, #0x70000000 @
|
||||
orr r3, r3, #0x3000 @ r3 = LCD1_BASE
|
||||
10: @ loop line @
|
||||
@
|
||||
ldrb r7, [r4], #1 @ r7 = *Y'_p++;
|
||||
ldrb r8, [r5], #1 @ r8 = *Cb_p++;
|
||||
ldrb r9, [r6], #1 @ r9 = *Cr_p++;
|
||||
@
|
||||
eor r14, r14, #0x80 @ flip pattern quadrant
|
||||
@
|
||||
sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@
|
||||
sub r8, r8, #128 @ Cb -= 128
|
||||
sub r9, r9, #128 @ Cr -= 128
|
||||
@
|
||||
add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
|
||||
add r10, r10, r8, asl #5 @
|
||||
add r10, r10, r9, asl #3 @
|
||||
add r10, r10, r9, asl #5 @
|
||||
add r10, r10, r9, asl #6 @
|
||||
@
|
||||
mov r8, r8, asl #1 @ r8 = bu = Cb*258
|
||||
add r8, r8, r8, asl #7 @
|
||||
@
|
||||
add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
|
||||
add r9, r9, r9, asl #4 @
|
||||
mov r9, r9, asl #3 @
|
||||
@
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7 @ r0 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
|
||||
add r0, r12, r0, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x100 @
|
||||
@
|
||||
add r0, r0, r12 @ b = r0 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r0, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r0, asr #15 @ clamp b
|
||||
mvnne r0, r12, lsr #15 @
|
||||
andne r0, r0, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
@
|
||||
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
mov r11, r11, lsr #8
|
||||
and r7, r7, #0x7e00
|
||||
orr r11, r11, r7, lsr #12
|
||||
mov r7, r7, lsr#4
|
||||
orr r0, r7, r0, lsr #10
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r11, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
@
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7 @ r0 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
|
||||
add r0, r12, r0, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x200 @
|
||||
@
|
||||
add r0, r0, r12 @ b = r0 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r0, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r0, asr #15 @ clamp b
|
||||
mvnne r0, r12, lsr #15 @
|
||||
andne r0, r0, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
|
||||
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
mov r11, r11, lsr #8
|
||||
and r7, r7, #0x7e00
|
||||
orr r11, r11, r7, lsr #12
|
||||
mov r7, r7, lsr#4
|
||||
orr r0, r7, r0, lsr #10
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r11, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7 @ r0 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
@ r8 = bu, r9 = rv, r10 = guv
|
||||
@
|
||||
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
|
||||
add r0, r12, r0, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
add r12, r14, #0x300 @
|
||||
@
|
||||
add r0, r0, r12 @ b = r0 + delta
|
||||
add r11, r11, r12, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r12, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r0, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r0, asr #15 @ clamp b
|
||||
mvnne r0, r12, lsr #15 @
|
||||
andne r0, r0, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
@
|
||||
ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
|
||||
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
mov r11, r11, lsr #8
|
||||
and r7, r7, #0x7e00
|
||||
orr r11, r11, r7, lsr #12
|
||||
mov r7, r7, lsr#4
|
||||
orr r0, r7, r0, lsr #10
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r11, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
|
||||
sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
|
||||
add r12, r7, r7, asl #2 @
|
||||
add r12, r12, r12, asl #4 @
|
||||
add r7, r12, r7, asl #6 @
|
||||
@ compute R, G, and B
|
||||
add r0, r8, r7 @ r0 = b' = Y + bu
|
||||
add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
|
||||
rsb r7, r10, r7 @ r7 = g' = Y + guv
|
||||
@
|
||||
sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
|
||||
add r0, r12, r0, lsr #8 @
|
||||
@
|
||||
sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
|
||||
add r11, r12, r11, lsr #8 @
|
||||
@
|
||||
sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
|
||||
add r7, r12, r7, lsr #8 @
|
||||
@
|
||||
@ This element is zero - use r14 @
|
||||
@
|
||||
add r0, r0, r14 @ b = r0 + delta
|
||||
add r11, r11, r14, lsl #1 @ r = r11 + delta*2
|
||||
add r7, r7, r14, lsr #1 @ g = r7 + delta/2
|
||||
@
|
||||
orr r12, r0, r11, asr #1 @ check if clamping is needed...
|
||||
orr r12, r12, r7 @ ...at all
|
||||
movs r12, r12, asr #15 @
|
||||
beq 15f @ no clamp @
|
||||
movs r12, r0, asr #15 @ clamp b
|
||||
mvnne r0, r12, lsr #15 @
|
||||
andne r0, r0, #0x7c00 @ mask b only if clamped
|
||||
movs r12, r11, asr #16 @ clamp r
|
||||
mvnne r11, r12, lsr #16 @
|
||||
movs r12, r7, asr #15 @ clamp g
|
||||
mvnne r7, r12, lsr #15 @
|
||||
15: @ no clamp @
|
||||
|
||||
and r11, r11, #0xf800 @ pack pixel
|
||||
mov r11, r11, lsr #8
|
||||
and r7, r7, #0x7e00
|
||||
orr r11, r11, r7, lsr #12
|
||||
mov r7, r7, lsr#4
|
||||
orr r0, r7, r0, lsr #10
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r11, [r3, #0x10] @ send MSB
|
||||
1: @ busy @
|
||||
ldr r7, [r3] @ r7 = LCD1_BASE
|
||||
tst r7, #LCD1_BUSY_MASK @ bridge busy?
|
||||
bne 1b @
|
||||
str r0, [r3, #0x10] @ send LSB
|
||||
|
||||
subs r1, r1, #2 @ subtract block from width
|
||||
bgt 10b @ loop line @
|
||||
@
|
||||
ldmpc regs=r4-r11 @ restore registers and return
|
||||
.ltorg @ dump constant pool
|
||||
.size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
|
||||
|
|
@ -273,15 +273,7 @@ void lcd_init_device(void)
|
|||
#if defined(HAVE_LCD_MODES)
|
||||
void lcd_set_mode(int mode)
|
||||
{
|
||||
if(mode==LCD_MODE_YUV) {
|
||||
/* Turn off the RGB buffer and enable the YUV buffer with zoom */
|
||||
IO_OSD_OSDWINMD0 |= 0x04;
|
||||
IO_OSD_VIDWINMD |= 0x01;
|
||||
#if LCD_NATIVE_WIDTH > 240
|
||||
IO_OSD_VIDWINMD |= (0x05<<2); /* This does a 2x zoom */
|
||||
#endif
|
||||
memset16(FRAME2, 0x0080, LCD_NATIVE_HEIGHT*(LCD_NATIVE_WIDTH+LCD_FUDGE));
|
||||
} else if(mode==LCD_MODE_RGB565) {
|
||||
if(mode==LCD_MODE_RGB565) {
|
||||
/* Turn on the RGB window, set it to 16 bit and turn YUV window off */
|
||||
IO_OSD_VIDWINMD &= ~(0x01);
|
||||
IO_OSD_OSDWIN0OFST = LCD_NATIVE_WIDTH / 16;
|
||||
|
|
@ -644,82 +636,6 @@ void lcd_pal256_update_pal(fb_data *palette)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Performance function to blit a YUV bitmap directly to the LCD */
|
||||
/* Show it rotated so the LCD_WIDTH is now the height */
|
||||
void lcd_blit_yuv(unsigned char * const src[3],
|
||||
int src_x, int src_y, int stride,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
unsigned char const * yuv_src[3];
|
||||
|
||||
if (!lcd_on)
|
||||
return;
|
||||
|
||||
/* y has to be on a 16 pixel boundary */
|
||||
y &= ~0xF;
|
||||
|
||||
if( ((y | x | height | width ) < 0)
|
||||
|| y>LCD_NATIVE_HEIGHT || x>LCD_NATIVE_WIDTH )
|
||||
return;
|
||||
|
||||
if(y+height>LCD_NATIVE_WIDTH)
|
||||
{
|
||||
height=LCD_NATIVE_WIDTH-y;
|
||||
}
|
||||
if(x+width>LCD_NATIVE_HEIGHT)
|
||||
{
|
||||
width=LCD_NATIVE_HEIGHT-x;
|
||||
}
|
||||
|
||||
/* Sorry, but width and height must be >= 2 or else */
|
||||
width &= ~1;
|
||||
height>>=1;
|
||||
|
||||
fb_data * dst = FRAME2
|
||||
+ ((LCD_NATIVE_WIDTH+LCD_FUDGE)*(LCD_NATIVE_HEIGHT-1))
|
||||
- (LCD_NATIVE_WIDTH+LCD_FUDGE)*x + y ;
|
||||
|
||||
/* Scope z */
|
||||
{
|
||||
off_t z;
|
||||
z = stride*src_y;
|
||||
yuv_src[0] = src[0] + z + src_x;
|
||||
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
|
||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||
}
|
||||
|
||||
int cbcr_remain=(stride>>1)-(width>>1);
|
||||
int y_remain=(stride<<1)-width;
|
||||
do
|
||||
{
|
||||
register int c_width=width;
|
||||
register unsigned int *c_dst=(unsigned int*)dst;
|
||||
do
|
||||
{
|
||||
register unsigned short Y=*((unsigned short*)yuv_src[0]);
|
||||
register unsigned short Yst=*((unsigned short*)(yuv_src[0]+stride));
|
||||
yuv_src[0]+=2;
|
||||
|
||||
register unsigned char Cb=*yuv_src[1]++;
|
||||
register unsigned char Cr=*yuv_src[2]++;
|
||||
|
||||
*c_dst = (Yst<<24) | (Cr << 16) | ((Y&0xFF)<<8) | Cb;
|
||||
*(c_dst - (LCD_NATIVE_WIDTH+LCD_FUDGE)/2) =
|
||||
( (Yst&0xFF00)<<16) | (Cr << 16) | (Y&0xFF00) | Cb;
|
||||
|
||||
c_dst -= (LCD_NATIVE_WIDTH+LCD_FUDGE);
|
||||
|
||||
c_width -= 2;
|
||||
} while (c_width);
|
||||
|
||||
yuv_src[0] += y_remain; /* Skip down two luma lines-width */
|
||||
yuv_src[1] += cbcr_remain; /* Skip down one chroma line-width/2 */
|
||||
yuv_src[2] += cbcr_remain;
|
||||
|
||||
dst+=2;
|
||||
} while (--height);
|
||||
}
|
||||
|
||||
void lcd_set_contrast(int val) {
|
||||
(void) val;
|
||||
// TODO:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue