summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/iaudio/x5/lcd-as-x5.S')
-rw-r--r--firmware/target/coldfire/iaudio/x5/lcd-as-x5.S131
1 files changed, 101 insertions, 30 deletions
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
index 11150203af..879235ebf2 100644
--- a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
+++ b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
@@ -45,6 +45,23 @@
45 * |B| |19611723 33976259 0| |Cr - 128| >> 26 45 * |B| |19611723 33976259 0| |Cr - 128| >> 26
46 * 46 *
47 * Needs EMAC set to saturated, signed integer mode. 47 * Needs EMAC set to saturated, signed integer mode.
48 *
49 * register usage:
50 * %a0 - LCD data port
51 * %a1 - Y pointer
52 * %a2 - C pointer
53 * %a3 - C width
54 * %a4 - Y end address
55 * %a5 - Y factor
56 * %a6 - BU factor
57 * %d0 - scratch
58 * %d1 - B, previous Y \ alternating
59 * %d2 - U / B, previous Y /
60 * %d3 - V / G
61 * %d4 - R / output pixel
62 * %d5 - GU factor
63 * %d6 - GV factor
64 * %d7 - RGB signed -> unsigned conversion mask
48 */ 65 */
49 .align 2 66 .align 2
50 .global lcd_write_yuv420_lines 67 .global lcd_write_yuv420_lines
@@ -55,8 +72,8 @@ lcd_write_yuv420_lines:
55 movem.l %d2-%d7/%a2-%a6, (%sp) 72 movem.l %d2-%d7/%a2-%a6, (%sp)
56 73
57 lea.l 0xf0008002, %a0 /* LCD data port */ 74 lea.l 0xf0008002, %a0 /* LCD data port */
58 movem.l (44+4, %sp), %a1-%a4 /* Y data, Cb data, Cr data, width */ 75 movem.l (44+4, %sp), %a1-%a3 /* Y data, C data, C width */
59 lea.l (%a1, %a4), %a4 /* end address */ 76 lea.l (%a1, %a3*2), %a4 /* Y end address */
60 77
61 move.l #19611723, %a5 /* y factor */ 78 move.l #19611723, %a5 /* y factor */
62 move.l #33976259, %a6 /* bu factor */ 79 move.l #33976259, %a6 /* bu factor */
@@ -65,11 +82,11 @@ lcd_write_yuv420_lines:
65 move.l #0x01040820, %d7 /* bitmask for signed->unsigned conversion 82 move.l #0x01040820, %d7 /* bitmask for signed->unsigned conversion
66 * of R, G and B within RGGB6666 at once */ 83 * of R, G and B within RGGB6666 at once */
67 84
68 /* chroma for (very) first & second pixel */ 85 /* chroma for first 2x2 block */
86 clr.l %d3 /* load v component */
87 move.b (%a2, %a3), %d3
69 clr.l %d2 /* load u component */ 88 clr.l %d2 /* load u component */
70 move.b (%a2)+, %d2 89 move.b (%a2)+, %d2
71 clr.l %d3 /* load v component */
72 move.b (%a3)+, %d3
73 moveq.l #-128, %d0 90 moveq.l #-128, %d0
74 add.l %d0, %d2 91 add.l %d0, %d2
75 add.l %d0, %d3 92 add.l %d0, %d3
@@ -80,9 +97,9 @@ lcd_write_yuv420_lines:
80 move.l #26881894, %d0 /* rv factor */ 97 move.l #26881894, %d0 /* rv factor */
81 mac.l %d0, %d3, %acc2 /* rv */ 98 mac.l %d0, %d3, %acc2 /* rv */
82 99
83 /* luma for (very) first pixel */ 100 /* luma for very first pixel (top left) */
84 clr.l %d1 101 clr.l %d1
85 move.b (%a1)+, %d1 102 move.b (%a1, %a3*2), %d1
86 moveq.l #-126, %d0 103 moveq.l #-126, %d0
87 add.l %d1, %d0 /* y' (-0.5 ... +0.5) */ 104 add.l %d1, %d0 /* y' (-0.5 ... +0.5) */
88 mac.l %a5, %d0, %acc0 105 mac.l %a5, %d0, %acc0
@@ -92,11 +109,11 @@ lcd_write_yuv420_lines:
92 bra.b .yuv_line_entry 109 bra.b .yuv_line_entry
93 110
94.yuv_line_loop: 111.yuv_line_loop:
95 /* chroma for first & second pixel */ 112 /* chroma for 2x2 pixel block */
113 clr.l %d3 /* load v component */
114 move.b (%a2, %a3), %d3
96 clr.l %d2 /* load u component */ 115 clr.l %d2 /* load u component */
97 move.b (%a2)+, %d2 116 move.b (%a2)+, %d2
98 clr.l %d3 /* load v component */
99 move.b (%a3)+, %d3
100 moveq.l #-128, %d0 117 moveq.l #-128, %d0
101 add.l %d0, %d2 118 add.l %d0, %d2
102 add.l %d0, %d3 119 add.l %d0, %d3
@@ -107,9 +124,9 @@ lcd_write_yuv420_lines:
107 move.l #26881894, %d0 /* rv factor */ 124 move.l #26881894, %d0 /* rv factor */
108 mac.l %d0, %d3, %acc2 /* rv */ 125 mac.l %d0, %d3, %acc2 /* rv */
109 126
110 /* luma for first pixel */ 127 /* luma for first pixel (top left) */
111 clr.l %d1 128 clr.l %d1
112 move.b (%a1)+, %d1 129 move.b (%a1, %a3*2), %d1
113 moveq.l #-126, %d0 130 moveq.l #-126, %d0
114 add.l %d1, %d0 /* y' (-0.5 ... +0.5) */ 131 add.l %d1, %d0 /* y' (-0.5 ... +0.5) */
115 mac.l %a5, %d0, %acc0 132 mac.l %a5, %d0, %acc0
@@ -140,9 +157,10 @@ lcd_write_yuv420_lines:
140 move.w %d4, (%a0) 157 move.w %d4, (%a0)
141 swap %d4 158 swap %d4
142 159
143 /* luma for second pixel as delta from the first */ 160 /* luma for second pixel (bottom left) as delta from the first */
144 clr.l %d0 161 clr.l %d2
145 move.b (%a1)+, %d0 162 move.b (%a1)+, %d2
163 move.l %d2, %d0
146 sub.l %d1, %d0 164 sub.l %d1, %d0
147 mac.l %a5, %d0, %acc0 165 mac.l %a5, %d0, %acc0
148 mac.l %a5, %d0, %acc1 166 mac.l %a5, %d0, %acc1
@@ -153,13 +171,45 @@ lcd_write_yuv420_lines:
153 171
154 /* convert to RGB666, pack and output */ 172 /* convert to RGB666, pack and output */
155 moveq.l #26, %d0 173 moveq.l #26, %d0
156 movclr.l %acc0, %d4 174 move.l %acc0, %d4
157 movclr.l %acc1, %d3 175 move.l %acc1, %d3
158 movclr.l %acc2, %d2 176 move.l %acc2, %d1
159 lsr.l %d0, %d4 177 lsr.l %d0, %d4
160 lsr.l %d0, %d3 178 lsr.l %d0, %d3
161 lsr.l %d0, %d2 179 lsr.l %d0, %d1
180
181 lsl.l #6, %d1
182 or.l %d3, %d1 /* |00000000|00000000|0000Rrrr|rrGggggg| */
183 lsl.l #7, %d1
184 or.l %d1, %d3 /* |00000000|00000Rrr|rrrGgggg|g0Gggggg| */
185 lsl.l #6, %d3
186 or.l %d3, %d4 /* |0000000R|rrrrrGgg|ggg0Gggg|ggBbbbbb| */
187 eor.l %d7, %d4 /* |0000000r|rrrrrggg|ggg0gggg|ggbbbbbb| */
188 swap %d4
189 move.w %d4, (%a0)
190 swap %d4
191
192 /* luma for third pixel (top right) as delta from the second */
193 clr.l %d1
194 move.b (%a1, %a3*2), %d1
195 move.l %d1, %d0
196 sub.l %d2, %d0
197 mac.l %a5, %d0, %acc0
198 mac.l %a5, %d0, %acc1
199 mac.l %a5, %d0, %acc2
200
201 move.w %d4, (%a0)
202 /* 2nd LCD write is delayed one pixel to use it for filling the EMAC latency */
162 203
204 /* convert to RGB666, pack and output */
205 moveq.l #26, %d0
206 move.l %acc0, %d4
207 move.l %acc1, %d3
208 move.l %acc2, %d2
209 lsr.l %d0, %d4
210 lsr.l %d0, %d3
211 lsr.l %d0, %d2
212
163 lsl.l #6, %d2 213 lsl.l #6, %d2
164 or.l %d3, %d2 /* |00000000|00000000|0000Rrrr|rrGggggg| */ 214 or.l %d3, %d2 /* |00000000|00000000|0000Rrrr|rrGggggg| */
165 lsl.l #7, %d2 215 lsl.l #7, %d2
@@ -171,24 +221,45 @@ lcd_write_yuv420_lines:
171 move.w %d4, (%a0) 221 move.w %d4, (%a0)
172 swap %d4 222 swap %d4
173 223
224 /* luma for fourth pixel (bottom right) as delta from the thrid */
225 clr.l %d2
226 move.b (%a1)+, %d2
227 move.l %d2, %d0
228 sub.l %d1, %d0
229 mac.l %a5, %d0, %acc0
230 mac.l %a5, %d0, %acc1
231 mac.l %a5, %d0, %acc2
232
233 move.w %d4, (%a0)
234 /* 2nd LCD write is delayed one pixel to use it for filling the EMAC latency */
235
236 /* convert to RGB666, pack and output */
237 moveq.l #26, %d0
238 movclr.l %acc0, %d4
239 movclr.l %acc1, %d3
240 movclr.l %acc2, %d1
241 lsr.l %d0, %d4
242 lsr.l %d0, %d3
243 lsr.l %d0, %d1
244
245 lsl.l #6, %d1
246 or.l %d3, %d1 /* |00000000|00000000|0000Rrrr|rrGggggg| */
247 lsl.l #7, %d1
248 or.l %d1, %d3 /* |00000000|00000Rrr|rrrGgggg|g0Gggggg| */
249 lsl.l #6, %d3
250 or.l %d3, %d4 /* |0000000R|rrrrrGgg|ggg0Gggg|ggBbbbbb| */
251 eor.l %d7, %d4 /* |0000000r|rrrrrggg|ggg0gggg|ggbbbbbb| */
252 swap %d4
253 move.w %d4, (%a0)
254 swap %d4
255
174 cmp.l %a1, %a4 /* run %a1 up to end of line */ 256 cmp.l %a1, %a4 /* run %a1 up to end of line */
175 bhi.w .yuv_line_loop 257 bhi.w .yuv_line_loop
176 258
177 tst.l (44+4, %sp) /* use original Y pointer as a flag to */
178 beq.b .yuv_exit /* distinguish between first and second */
179 clr.l (44+4, %sp) /* pixel line */
180
181 /* Rewind chroma pointers */
182 movem.l (44+8, %sp), %a2-%a4 /* Cb data, Cr data, width */
183 lea.l (%a1, %a4), %a4 /* end address */
184 bra.w .yuv_line_loop
185
186.yuv_exit:
187 move.w %d4, (%a0) /* write (very) last 2nd word */ 259 move.w %d4, (%a0) /* write (very) last 2nd word */
188 260
189 movem.l (%sp), %d2-%d7/%a2-%a6 261 movem.l (%sp), %d2-%d7/%a2-%a6
190 lea.l (44, %sp), %sp /* restore registers */ 262 lea.l (44, %sp), %sp /* restore registers */
191
192 rts 263 rts
193.yuv_end: 264.yuv_end:
194 .size lcd_write_yuv420_lines, yuv_end - lcd_write_yuv420_lines 265 .size lcd_write_yuv420_lines, yuv_end - lcd_write_yuv420_lines