diff options
Diffstat (limited to 'firmware/target/coldfire/iaudio/x5/lcd-as-x5.S')
-rw-r--r-- | firmware/target/coldfire/iaudio/x5/lcd-as-x5.S | 131 |
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 |