1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 by Jens Arnold
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
23 .section .icode, "ax", @progbits
25 /* lcd_write_yuv420_lines()
27 * See http://en.wikipedia.org/wiki/YCbCr
28 * ITU-R BT.601 (formerly CCIR 601):
29 * |Y'| | 0.299000 0.587000 0.114000| |R|
30 * |Pb| = |-0.168736 -0.331264 0.500000| |G| or 0.564334*(B - Y')
31 * |Pr| | 0.500000 -0.418688 0.081312| |B| or 0.713267*(R - Y')
32 * Scaled, normalized and rounded:
33 * |Y'| | 65 129 25| |R| + 16 : 16->235
34 * |Cb| = |-38 -74 112| |G| + 128 : 16->240
35 * |Cr| |112 -94 -18| |B| + 128 : 16->240
38 * |R| |1.000000 0.000000 1.402000| |Y'|
39 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
40 * |B| |1.000000 1.772000 0.000000| |Pr|
41 * Scaled, normalized, rounded and tweaked to yield RGB565:
42 * |R| |19611723 0 26881894| |Y' - 16| >> 27
43 * |G| = |19611723 -6406711 -13692816| |Cb - 128| >> 26
44 * |B| |19611723 33976259 0| |Cr - 128| >> 27
46 * Needs EMAC set to saturated, signed integer mode.
57 * %d1 - B, previous Y \ alternating
58 * %d2 - U / B, previous Y /
60 * %d4 - R / output pixel
63 * %d7 - RGB signed -> unsigned conversion mask
66 .global lcd_write_yuv420_lines
67 .type lcd_write_yuv420_lines, @function
69 lcd_write_yuv420_lines:
70 lea.l (-44, %sp), %sp /* free up some registers */
71 movem.l %d2-%d7/%a2-%a6, (%sp)
73 lea.l 0xf0000002, %a0 /* LCD data port */
74 movem.l (44+4, %sp), %a1-%a3 /* Y data, C data, C width */
75 lea.l (%a1, %a3*2), %a4 /* Y end address */
77 move.l #19611723, %a5 /* y factor */
78 move.l #33976259, %a6 /* bu factor */
79 move.l #-6406711, %d5 /* gu factor */
80 move.l #-13692816, %d6 /* gv factor */
81 move.l #0x8410, %d7 /* bitmask for signed->unsigned conversion
82 * of R, G and B within RGB565 at once */
84 /* chroma for first 2x2 pixel block */
85 clr.l %d3 /* load v component */
86 move.b (%a2, %a3), %d3
87 clr.l %d2 /* load u component */
93 mac.l %a6, %d2, %acc0 /* bu */
94 mac.l %d5, %d2, %acc1 /* gu */
95 mac.l %d6, %d3, %acc1 /* gv */
96 move.l #26881894, %d0 /* rv factor */
97 mac.l %d0, %d3, %acc2 /* rv */
99 /* luma for very first pixel (top left) */
101 move.b (%a1, %a3*2), %d1
103 add.l %d1, %d0 /* y' (-0.5 ... +0.5) */
104 mac.l %a5, %d0, %acc0
105 mac.l %a5, %d0, %acc1
106 mac.l %a5, %d0, %acc2
108 bra.b .yuv_line_entry
111 /* chroma for 2x2 pixel block */
112 clr.l %d3 /* load v component */
113 move.b (%a2, %a3), %d3
114 clr.l %d2 /* load u component */
120 mac.l %a6, %d2, %acc0 /* bu */
121 mac.l %d5, %d2, %acc1 /* gu */
122 mac.l %d6, %d3, %acc1 /* gv */
123 move.l #26881894, %d0 /* rv factor */
124 mac.l %d0, %d3, %acc2 /* rv */
126 /* luma for first pixel (top left) */
128 move.b (%a1, %a3*2), %d1
130 add.l %d1, %d0 /* y' (-0.5 ... +0.5) */
131 mac.l %a5, %d0, %acc0
132 mac.l %a5, %d0, %acc1
133 mac.l %a5, %d0, %acc2
136 /* LCD write is delayed one pixel to use it for filling the EMAC latency */
138 /* convert to RGB565, pack and output */
154 /* luma for second pixel (bottom left) as delta from the first */
159 mac.l %a5, %d0, %acc0
160 mac.l %a5, %d0, %acc1
161 mac.l %a5, %d0, %acc2
164 /* LCD write is delayed one pixel to use it for filling the EMAC latency */
166 /* convert to RGB565, pack and output */
181 /* luma for third pixel (top right) as delta from the second */
183 move.b (%a1, %a3*2), %d1
186 mac.l %a5, %d0, %acc0
187 mac.l %a5, %d0, %acc1
188 mac.l %a5, %d0, %acc2
191 /* LCD write is delayed one pixel to use it for filling the EMAC latency */
193 /* convert to RGB565, pack and output */
208 /* luma for fourth pixel (bottom right) as delta from the third */
213 mac.l %a5, %d0, %acc0
214 mac.l %a5, %d0, %acc1
215 mac.l %a5, %d0, %acc2
218 /* LCD write is delayed one pixel to use it for filling the EMAC latency */
220 /* convert to RGB565, pack and output */
235 cmp.l %a1, %a4 /* run %a1 up to end of line */
238 move.w %d4, (%a0) /* write (very) last pixel */
240 movem.l (%sp), %d2-%d7/%a2-%a6
241 lea.l (44, %sp), %sp /* restore registers */
244 .size lcd_write_yuv420_lines, .yuv_end - lcd_write_yuv420_lines