1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id:$
*
* Copyright (C) 2010 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"
.section .icode, "ax", %progbits
/****************************************************************************
* void lcd_yuv_write_inner_loop(unsigned char const * const ysrc,
* unsigned char const * const usrc,
* unsigned char const * const vsrc,
* int width);
*
* 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
*
*/
.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
#if 1
11: @ while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK));
ldr r11, [r4, #0x20] @
tst r11, #0x1000000 @
beq 11b @
#endif
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
|