summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/iriver/h300/lcd-as-h300.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/iriver/h300/lcd-as-h300.S')
-rwxr-xr-xfirmware/target/coldfire/iriver/h300/lcd-as-h300.S346
1 files changed, 120 insertions, 226 deletions
diff --git a/firmware/target/coldfire/iriver/h300/lcd-as-h300.S b/firmware/target/coldfire/iriver/h300/lcd-as-h300.S
index ae55dfb224..1873b905c6 100755
--- a/firmware/target/coldfire/iriver/h300/lcd-as-h300.S
+++ b/firmware/target/coldfire/iriver/h300/lcd-as-h300.S
@@ -22,7 +22,7 @@
22 22
23 .section .icode, "ax", @progbits 23 .section .icode, "ax", @progbits
24 24
25/* lcd_write_yuv420_lines(), based on lcd-as-x5.S 25/* lcd_write_yuv420_lines()
26 * 26 *
27 * See http://en.wikipedia.org/wiki/YCbCr 27 * See http://en.wikipedia.org/wiki/YCbCr
28 * ITU-R BT.601 (formerly CCIR 601): 28 * ITU-R BT.601 (formerly CCIR 601):
@@ -38,252 +38,146 @@
38 * |R| |1.000000 0.000000 1.402000| |Y'| 38 * |R| |1.000000 0.000000 1.402000| |Y'|
39 * |G| = |1.000000 -0.334136 -0.714136| |Pb| 39 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
40 * |B| |1.000000 1.772000 0.000000| |Pr| 40 * |B| |1.000000 1.772000 0.000000| |Pr|
41 * Scaled, normalized, rounded and tweaked to yield RGB666, as converting 41 * Scaled, normalized, rounded and tweaked to yield RGB565:
42 * directly to RGB565 gives too much roundoff error: 42 * |R| |19611723 0 26881894| |Y' - 16| >> 27
43 * |R| |74 0 101| |Y' - 16| / 256 43 * |G| = |19611723 -6406711 -13692816| |Cb - 128| >> 26
44 * |G| = |74 -24 -51| |Cb - 128| / 256 44 * |B| |19611723 33976259 0| |Cr - 128| >> 27
45 * |B| |74 128 0| |Cr - 128| / 256 45 *
46 * Needs EMAC set to saturated, signed integer mode.
46 */ 47 */
47
48 .align 2 48 .align 2
49 .global lcd_write_yuv420_lines 49 .global lcd_write_yuv420_lines
50 .type lcd_write_yuv420_lines, @function 50 .type lcd_write_yuv420_lines, @function
51 51
52lcd_write_yuv420_lines: 52lcd_write_yuv420_lines:
53 lea.l (-36, %sp), %sp /* free up some registers */ 53 lea.l (-44, %sp), %sp /* free up some registers */
54 movem.l %d2-%d6/%a2-%a5, (%sp) 54 movem.l %d2-%d7/%a2-%a6, (%sp)
55 55
56 lea.l 0xf0000002, %a0 /* LCD data port */ 56 lea.l 0xf0000002, %a0 /* LCD data port */
57 movem.l (36+4, %sp), %a1-%a5 /* Y data, Cb data, guv storage, Cr data, width */ 57 movem.l (44+4, %sp), %a1-%a4 /* Y data, Cb data, Cr data, width */
58 lea.l (%a1, %a5), %a5 /* end address */ 58 lea.l (%a1, %a4), %a4 /* end address */
59 59
60.yuv_line_loop1: 60 move.l #19611723, %a5 /* y factor */
61 /* chroma for first & second pixel */ 61 move.l #33976259, %a6 /* bu factor */
62 clr.l %d1 /* load bu component */ 62 move.l #-6406711, %d5 /* gu factor */
63 move.b (%a2), %d1 63 move.l #-13692816, %d6 /* gv factor */
64 clr.l %d3 /* load rv component */ 64 move.l #0x8410, %d7 /* bitmask for signed->unsigned conversion
65 move.b (%a4), %d3 65 * of R, G and B within RGB565 at once */
66
67 /* chroma for (very) first & second pixel */
68 clr.l %d2 /* load u component */
69 move.b (%a2)+, %d2
70 clr.l %d3 /* load v component */
71 move.b (%a3)+, %d3
66 moveq.l #-128, %d0 72 moveq.l #-128, %d0
67 add.l %d0, %d1 73 add.l %d0, %d2
68 add.l %d0, %d3 74 add.l %d0, %d3
69 75
70 move.l %d1, %d2 /* %d2 = cb component for guv */ 76 mac.l %a6, %d2, %acc0 /* bu */
71 asr.l #1, %d1 /* %d1 = 128 * (Cb - 128) / 256 */ 77 mac.l %d5, %d2, %acc1 /* gu */
72 move.b %d1, (%a2)+ /* save bu for next line */ 78 mac.l %d6, %d3, %acc1 /* gv */
73 moveq.l #-24, %d0 79 move.l #26881894, %d0 /* rv factor */
74 muls.w %d0, %d2 /* %d2 = -24 * (Cb - 128)*/ 80 mac.l %d0, %d3, %acc2 /* rv */
75 moveq.l #-51, %d0
76 muls.w %d3, %d0
77 add.l %d0, %d2 /* %d2 = -24 * (Cb - 128) - 51 * (Cr - 128) */
78 asr.l #8, %d2
79 move.b %d2, (%a3)+ /* save guv for next line */
80 moveq.l #101, %d0
81 muls.w %d0, %d3 /* %d3 = 101 * (Cr - 128) */
82 asr.l #8, %d3
83 move.b %d3, (%a4)+ /* save rv for next line */
84 81
85 /* luma for first pixel */ 82 /* luma for (very) first pixel */
86 clr.l %d4 /* load y component */ 83 clr.l %d1
87 move.b (%a1)+, %d4 84 move.b (%a1)+, %d1
88 moveq.l #74, %d0 85 moveq.l #-126, %d0
89 muls.w %d0, %d4 /* %d4 = 36 * Y */ 86 add.l %d1, %d0 /* y' (-0.5 ... +0.5) */
90 asr.l #8, %d4 87 mac.l %a5, %d0, %acc0
91 subq.l #4, %d4 /* correction for (Y - 16) and rounding */ 88 mac.l %a5, %d0, %acc1
92 move.l %d4, %d5 89 mac.l %a5, %d0, %acc2
93 move.l %d4, %d6
94
95 /* combine & write first pixel */
96 add.l %d1, %d4 /* %d4 = blue */
97 add.l %d2, %d5 /* %d5 = green */
98 add.l %d3, %d6 /* %d6 = red */
99
100 move.l %d4, %d0 /* clamping */
101 or.l %d5, %d0
102 or.l %d6, %d0
103 asr.l #6, %d0
104 beq.s .yuv_all_ok1
105 moveq.l #63, %d0
106 cmp.l %d0, %d4
107 bls.s .yuv_blue_ok1
108 spl.b %d4
109 and.l %d0, %d4
110.yuv_blue_ok1:
111 cmp.l %d0, %d5
112 bls.s .yuv_green_ok1
113 spl.b %d5
114 and.l %d0, %d5
115.yuv_green_ok1:
116 cmp.l %d0, %d6
117 bls.s .yuv_red_ok1
118 spl.b %d6
119 and.l %d0, %d6
120.yuv_red_ok1:
121.yuv_all_ok1:
122
123 lsr.l #1, %d6 /* pack, convert to RGB565 and output */
124 lsr.l #1, %d4
125 lsl.l #6, %d6
126 or.l %d6, %d5
127 lsl.l #5, %d5
128 or.l %d5, %d4
129 move.w %d4, (%a0)
130
131 /* luma for second pixel */
132 clr.l %d4 /* load y component */
133 move.b (%a1)+, %d4
134 moveq.l #74, %d0
135 muls.w %d0, %d4 /* %d4 = 36 * Y */
136 asr.l #8, %d4
137 subq.l #4, %d4 /* correction for (Y - 16) and rounding */
138
139 /* combine & write second pixel */
140 add.l %d4, %d1 /* %d1 = blue */
141 add.l %d4, %d2 /* %d2 = green */
142 add.l %d4, %d3 /* %d3 = red */
143
144 move.l %d1, %d0 /* clamping */
145 or.l %d2, %d0
146 or.l %d3, %d0
147 asr.l #6, %d0
148 beq.s .yuv_all_ok2
149 moveq.l #63, %d0
150 cmp.l %d0, %d1
151 bls.s .yuv_blue_ok2
152 spl.b %d1
153 and.l %d0, %d1
154.yuv_blue_ok2:
155 cmp.l %d0, %d2
156 bls.s .yuv_green_ok2
157 spl.b %d2
158 and.l %d0, %d2
159.yuv_green_ok2:
160 cmp.l %d0, %d3
161 bls.s .yuv_red_ok2
162 spl.b %d3
163 and.l %d0, %d3
164.yuv_red_ok2:
165.yuv_all_ok2:
166 90
167 lsr.l #1, %d3 /* pack, convert to RGB565 and output */ 91 bra.b .yuv_line_entry
168 lsr.l #1, %d1
169 lsl.l #6, %d3
170 or.l %d3, %d2
171 lsl.l #5, %d2
172 or.l %d2, %d1
173 move.w %d1, (%a0)
174 92
175 cmp.l %a1,%a5 /* run %a1 up to end of line */ 93.yuv_line_loop:
176 bhi.w .yuv_line_loop1 94 /* chroma for first & second pixel */
177 95 clr.l %d2 /* load u component */
178 /* Rewind chroma pointers */ 96 move.b (%a2)+, %d2
179 movem.l (36+8, %sp), %a2-%a5 /* bu data, guv data, rv data, width */ 97 clr.l %d3 /* load v component */
180 lea.l (%a1, %a5), %a5 /* next end address */ 98 move.b (%a3)+, %d3
99 moveq.l #-128, %d0
100 add.l %d0, %d2
101 add.l %d0, %d3
181 102
182.yuv_line_loop2: 103 mac.l %a6, %d2, %acc0 /* bu */
183 /* read saved chromas and sign extend */ 104 mac.l %d5, %d2, %acc1 /* gu */
184 move.b (%a2)+, %d1 105 mac.l %d6, %d3, %acc1 /* gv */
185 extb.l %d1 106 move.l #26881894, %d0 /* rv factor */
186 move.b (%a3)+, %d2 107 mac.l %d0, %d3, %acc2 /* rv */
187 extb.l %d2
188 move.b (%a4)+, %d3
189 extb.l %d3
190 108
191 /* luma for first pixel */ 109 /* luma for first pixel */
192 clr.l %d4 /* load y component */ 110 clr.l %d1
193 move.b (%a1)+, %d4 111 move.b (%a1)+, %d1
194 moveq.l #74, %d0 112 moveq.l #-126, %d0
195 muls.w %d0, %d4 /* %d4 = 36 * Y */ 113 add.l %d1, %d0 /* y' (-0.5 ... +0.5) */
196 asr.l #8, %d4 114 mac.l %a5, %d0, %acc0
197 subq.l #4, %d4 /* correction for (Y - 16) and rounding */ 115 mac.l %a5, %d0, %acc1
198 move.l %d4, %d5 116 mac.l %a5, %d0, %acc2
199 move.l %d4, %d6
200 117
201 /* combine & write first pixel */ 118 move.w %d4, (%a0)
202 add.l %d1, %d4 /* %d4 = blue */ 119 /* LCD write is delayed one pixel to use it for filling the EMAC latency */
203 add.l %d2, %d5 /* %d5 = green */ 120
204 add.l %d3, %d6 /* %d6 = red */ 121 /* convert to RGB565, pack and output */
122.yuv_line_entry:
123 moveq.l #27, %d0
124 move.l %acc0, %d2
125 move.l %acc1, %d3
126 move.l %acc2, %d4
127 lsr.l %d0, %d2
128 lsr.l %d0, %d4
129 moveq.l #26, %d0
130 lsr.l %d0, %d3
131 lsl.l #6, %d4
132 or.l %d3, %d4
133 lsl.l #5, %d4
134 or.l %d2, %d4
135 eor.l %d7, %d4
136
137 /* luma for second pixel as delta from the first */
138 clr.l %d0
139 move.b (%a1)+, %d0
140 sub.l %d1, %d0
141 mac.l %a5, %d0, %acc0
142 mac.l %a5, %d0, %acc1
143 mac.l %a5, %d0, %acc2
144
145 move.w %d4, (%a0)
146 /* LCD write is delayed one pixel to use it for filling the EMAC latency */
147
148 /* convert to RGB565, pack and output */
149 moveq.l #27, %d0
150 movclr.l %acc0, %d2
151 movclr.l %acc1, %d3
152 movclr.l %acc2, %d4
153 lsr.l %d0, %d2
154 lsr.l %d0, %d4
155 moveq.l #26, %d0
156 lsr.l %d0, %d3
157 lsl.l #6, %d4
158 or.l %d3, %d4
159 lsl.l #5, %d4
160 or.l %d2, %d4
161 eor.l %d7, %d4
162
163 cmp.l %a1, %a4 /* run %a1 up to end of line */
164 bhi.w .yuv_line_loop
205 165
206 move.l %d4, %d0 /* clamping */ 166 tst.l (44+4, %sp) /* use original Y pointer as a flag to */
207 or.l %d5, %d0 167 beq.b .yuv_exit /* distinguish between first and second */
208 or.l %d6, %d0 168 clr.l (44+4, %sp) /* pixel line */
209 asr.l #6, %d0
210 beq.s .yuv_all_ok3
211 moveq.l #63, %d0
212 cmp.l %d0, %d4
213 bls.s .yuv_blue_ok3
214 spl.b %d4
215 and.l %d0, %d4
216.yuv_blue_ok3:
217 cmp.l %d0, %d5
218 bls.s .yuv_green_ok3
219 spl.b %d5
220 and.l %d0, %d5
221.yuv_green_ok3:
222 cmp.l %d0, %d6
223 bls.s .yuv_red_ok3
224 spl.b %d6
225 and.l %d0, %d6
226.yuv_red_ok3:
227.yuv_all_ok3:
228 169
229 lsr.l #1, %d6 /* pack, convert to RGB565 and output */ 170 /* Rewind chroma pointers */
230 lsr.l #1, %d4 171 movem.l (44+8, %sp), %a2-%a4 /* Cb data, Cr data, width */
231 lsl.l #6, %d6 172 lea.l (%a1, %a4), %a4 /* end address */
232 or.l %d6, %d5 173 bra.w .yuv_line_loop
233 lsl.l #5, %d5
234 or.l %d5, %d4
235 move.w %d4, (%a0)
236
237 /* luma for second pixel */
238 clr.l %d4 /* load y component */
239 move.b (%a1)+, %d4
240 moveq.l #74, %d0
241 muls.w %d0, %d4 /* %d4 = 36 * Y */
242 asr.l #8, %d4
243 subq.l #4, %d4 /* correction for (Y - 16) and rounding */
244
245 /* combine & write second pixel */
246 add.l %d4, %d1 /* %d1 = blue */
247 add.l %d4, %d2 /* %d2 = green */
248 add.l %d4, %d3 /* %d3 = red */
249 174
250 move.l %d1, %d0 /* clamping */ 175.yuv_exit:
251 or.l %d2, %d0 176 move.w %d4, (%a0) /* write (very) last pixel */
252 or.l %d3, %d0
253 asr.l #6, %d0
254 beq.s .yuv_all_ok4
255 moveq.l #63, %d0
256 cmp.l %d0, %d1
257 bls.s .yuv_blue_ok4
258 spl.b %d1
259 and.l %d0, %d1
260.yuv_blue_ok4:
261 cmp.l %d0, %d2
262 bls.s .yuv_green_ok4
263 spl.b %d2
264 and.l %d0, %d2
265.yuv_green_ok4:
266 cmp.l %d0, %d3
267 bls.s .yuv_red_ok4
268 spl.b %d3
269 and.l %d0, %d3
270.yuv_red_ok4:
271.yuv_all_ok4:
272
273 lsr.l #1, %d3 /* pack, convert to RGB565 and output */
274 lsr.l #1, %d1
275 lsl.l #6, %d3
276 or.l %d3, %d2
277 lsl.l #5, %d2
278 or.l %d2, %d1
279 move.w %d1, (%a0)
280
281 cmp.l %a1, %a5 /* run %a1 up to end of line */
282 bhi.w .yuv_line_loop2
283 177
284 movem.l (%sp), %d2-%d6/%a2-%a5 178 movem.l (%sp), %d2-%d7/%a2-%a6
285 lea.l (36, %sp), %sp /* restore registers */ 179 lea.l (44, %sp), %sp /* restore registers */
286 180
287 rts 181 rts
288.lcd_write_yuv420_lines_end: 182.yuv_end:
289 .size lcd_write_yuv420_lines, .lcd_write_yuv420_lines_end - lcd_write_yuv420_lines 183 .size lcd_write_yuv420_lines, .yuv_end - lcd_write_yuv420_lines