summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/iaudio
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/iaudio')
-rw-r--r--firmware/target/coldfire/iaudio/x5/lcd-as-x5.S242
-rw-r--r--firmware/target/coldfire/iaudio/x5/lcd-x5.c63
2 files changed, 0 insertions, 305 deletions
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
index e6621e1dea..b319d745ca 100644
--- a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
+++ b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
@@ -25,248 +25,6 @@
25 25
26 .section .icode,"ax",@progbits 26 .section .icode,"ax",@progbits
27 27
28/* begin lcd_write_yuv420_lines
29 *
30 * See http://en.wikipedia.org/wiki/YCbCr
31 * ITU-R BT.601 (formerly CCIR 601):
32 * |Y'| | 0.299000 0.587000 0.114000| |R|
33 * |Pb| = |-0.168736 -0.331264 0.500000| |G| or 0.564334*(B - Y')
34 * |Pr| | 0.500000 -0.418688 0.081312| |B| or 0.713267*(R - Y')
35 * Scaled, normalized and rounded:
36 * |Y'| | 65 129 25| |R| + 16 : 16->235
37 * |Cb| = |-38 -74 112| |G| + 128 : 16->240
38 * |Cr| |112 -94 -18| |B| + 128 : 16->240
39 *
40 * The inverse:
41 * |R| |1.000000 -0.000001 1.402000| |Y'|
42 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
43 * |B| |1.000000 1.772000 0.000000| |Pr|
44 * Scaled, normalized, rounded and tweaked to yield RGB 666:
45 * |R| |19611723 0 26881894| |Y' - 16| >> 26
46 * |G| = |19611723 -6406711 -13692816| |Cb - 128| >> 26
47 * |B| |19611723 33976259 0| |Cr - 128| >> 26
48 *
49 * Needs EMAC set to saturated, signed integer mode.
50 *
51 * register usage:
52 * %a0 - LCD data port
53 * %a1 - Y pointer
54 * %a2 - C pointer
55 * %a3 - C width
56 * %a4 - Y end address
57 * %a5 - Y factor
58 * %a6 - BU factor
59 * %d0 - scratch
60 * %d1 - B, previous Y \ alternating
61 * %d2 - U / B, previous Y /
62 * %d3 - V / G
63 * %d4 - R / output pixel
64 * %d5 - GU factor
65 * %d6 - GV factor
66 * %d7 - RGB signed -> unsigned conversion mask
67 */
68 .align 2
69 .global lcd_write_yuv420_lines
70 .type lcd_write_yuv420_lines, @function
71
72lcd_write_yuv420_lines:
73 lea.l (-44, %sp), %sp /* free up some registers */
74 movem.l %d2-%d7/%a2-%a6, (%sp)
75
76 lea.l 0xf0008002, %a0 /* LCD data port */
77 movem.l (44+4, %sp), %a1-%a3 /* Y data, C data, C width */
78 lea.l (%a1, %a3*2), %a4 /* Y end address */
79
80 move.l #19611723, %a5 /* y factor */
81 move.l #33976259, %a6 /* bu factor */
82 move.l #-6406711, %d5 /* gu factor */
83 move.l #-13692816, %d6 /* gv factor */
84 move.l #0x01040820, %d7 /* bitmask for signed->unsigned conversion
85 * of R, G and B within RGGB6666 at once */
86
87 /* chroma for first 2x2 block */
88 clr.l %d3 /* load v component */
89 move.b (%a2, %a3), %d3
90 clr.l %d2 /* load u component */
91 move.b (%a2)+, %d2
92 moveq.l #-128, %d0
93 add.l %d0, %d2
94 add.l %d0, %d3
95
96 mac.l %a6, %d2, %acc0 /* bu */
97 mac.l %d5, %d2, %acc1 /* gu */
98 mac.l %d6, %d3, %acc1 /* gv */
99 move.l #26881894, %d0 /* rv factor */
100 mac.l %d0, %d3, %acc2 /* rv */
101
102 /* luma for very first pixel (top left) */
103 clr.l %d1
104 move.b (%a1, %a3*2), %d1
105 moveq.l #-126, %d0
106 add.l %d1, %d0 /* y' (-0.5 ... +0.5) */
107 mac.l %a5, %d0, %acc0
108 mac.l %a5, %d0, %acc1
109 mac.l %a5, %d0, %acc2
110
111 bra.b .yuv_line_entry
112
113.yuv_line_loop:
114 /* chroma for 2x2 pixel block */
115 clr.l %d3 /* load v component */
116 move.b (%a2, %a3), %d3
117 clr.l %d2 /* load u component */
118 move.b (%a2)+, %d2
119 moveq.l #-128, %d0
120 add.l %d0, %d2
121 add.l %d0, %d3
122
123 mac.l %a6, %d2, %acc0 /* bu */
124 mac.l %d5, %d2, %acc1 /* gu */
125 mac.l %d6, %d3, %acc1 /* gv */
126 move.l #26881894, %d0 /* rv factor */
127 mac.l %d0, %d3, %acc2 /* rv */
128
129 /* luma for first pixel (top left) */
130 clr.l %d1
131 move.b (%a1, %a3*2), %d1
132 moveq.l #-126, %d0
133 add.l %d1, %d0 /* y' (-0.5 ... +0.5) */
134 mac.l %a5, %d0, %acc0
135 mac.l %a5, %d0, %acc1
136 mac.l %a5, %d0, %acc2
137
138 move.w %d4, (%a0)
139 /* 2nd LCD write is delayed one pixel to use it for filling the EMAC latency */
140
141 /* convert to RGB666, pack and output */
142.yuv_line_entry:
143 moveq.l #26, %d0
144 move.l %acc0, %d4
145 move.l %acc1, %d3
146 move.l %acc2, %d2
147 lsr.l %d0, %d4
148 lsr.l %d0, %d3
149 lsr.l %d0, %d2
150
151 lsl.l #6, %d2
152 or.l %d3, %d2 /* |00000000|00000000|0000Rrrr|rrGggggg| */
153 lsl.l #7, %d2
154 or.l %d2, %d3 /* |00000000|00000Rrr|rrrGgggg|g0Gggggg| */
155 lsl.l #6, %d3
156 or.l %d3, %d4 /* |0000000R|rrrrrGgg|ggg0Gggg|ggBbbbbb| */
157 eor.l %d7, %d4 /* |0000000r|rrrrrggg|ggg0gggg|ggbbbbbb| */
158 swap %d4
159 move.w %d4, (%a0)
160 swap %d4
161
162 /* luma for second pixel (bottom left) as delta from the first */
163 clr.l %d2
164 move.b (%a1)+, %d2
165 move.l %d2, %d0
166 sub.l %d1, %d0
167 mac.l %a5, %d0, %acc0
168 mac.l %a5, %d0, %acc1
169 mac.l %a5, %d0, %acc2
170
171 move.w %d4, (%a0)
172 /* 2nd LCD write is delayed one pixel to use it for filling the EMAC latency */
173
174 /* convert to RGB666, pack and output */
175 moveq.l #26, %d0
176 move.l %acc0, %d4
177 move.l %acc1, %d3
178 move.l %acc2, %d1
179 lsr.l %d0, %d4
180 lsr.l %d0, %d3
181 lsr.l %d0, %d1
182
183 lsl.l #6, %d1
184 or.l %d3, %d1 /* |00000000|00000000|0000Rrrr|rrGggggg| */
185 lsl.l #7, %d1
186 or.l %d1, %d3 /* |00000000|00000Rrr|rrrGgggg|g0Gggggg| */
187 lsl.l #6, %d3
188 or.l %d3, %d4 /* |0000000R|rrrrrGgg|ggg0Gggg|ggBbbbbb| */
189 eor.l %d7, %d4 /* |0000000r|rrrrrggg|ggg0gggg|ggbbbbbb| */
190 swap %d4
191 move.w %d4, (%a0)
192 swap %d4
193
194 /* luma for third pixel (top right) as delta from the second */
195 clr.l %d1
196 move.b (%a1, %a3*2), %d1
197 move.l %d1, %d0
198 sub.l %d2, %d0
199 mac.l %a5, %d0, %acc0
200 mac.l %a5, %d0, %acc1
201 mac.l %a5, %d0, %acc2
202
203 move.w %d4, (%a0)
204 /* 2nd LCD write is delayed one pixel to use it for filling the EMAC latency */
205
206 /* convert to RGB666, pack and output */
207 moveq.l #26, %d0
208 move.l %acc0, %d4
209 move.l %acc1, %d3
210 move.l %acc2, %d2
211 lsr.l %d0, %d4
212 lsr.l %d0, %d3
213 lsr.l %d0, %d2
214
215 lsl.l #6, %d2
216 or.l %d3, %d2 /* |00000000|00000000|0000Rrrr|rrGggggg| */
217 lsl.l #7, %d2
218 or.l %d2, %d3 /* |00000000|00000Rrr|rrrGgggg|g0Gggggg| */
219 lsl.l #6, %d3
220 or.l %d3, %d4 /* |0000000R|rrrrrGgg|ggg0Gggg|ggBbbbbb| */
221 eor.l %d7, %d4 /* |0000000r|rrrrrggg|ggg0gggg|ggbbbbbb| */
222 swap %d4
223 move.w %d4, (%a0)
224 swap %d4
225
226 /* luma for fourth pixel (bottom right) as delta from the thrid */
227 clr.l %d2
228 move.b (%a1)+, %d2
229 move.l %d2, %d0
230 sub.l %d1, %d0
231 mac.l %a5, %d0, %acc0
232 mac.l %a5, %d0, %acc1
233 mac.l %a5, %d0, %acc2
234
235 move.w %d4, (%a0)
236 /* 2nd LCD write is delayed one pixel to use it for filling the EMAC latency */
237
238 /* convert to RGB666, pack and output */
239 moveq.l #26, %d0
240 movclr.l %acc0, %d4
241 movclr.l %acc1, %d3
242 movclr.l %acc2, %d1
243 lsr.l %d0, %d4
244 lsr.l %d0, %d3
245 lsr.l %d0, %d1
246
247 lsl.l #6, %d1
248 or.l %d3, %d1 /* |00000000|00000000|0000Rrrr|rrGggggg| */
249 lsl.l #7, %d1
250 or.l %d1, %d3 /* |00000000|00000Rrr|rrrGgggg|g0Gggggg| */
251 lsl.l #6, %d3
252 or.l %d3, %d4 /* |0000000R|rrrrrGgg|ggg0Gggg|ggBbbbbb| */
253 eor.l %d7, %d4 /* |0000000r|rrrrrggg|ggg0gggg|ggbbbbbb| */
254 swap %d4
255 move.w %d4, (%a0)
256 swap %d4
257
258 cmp.l %a1, %a4 /* run %a1 up to end of line */
259 bhi.w .yuv_line_loop
260
261 move.w %d4, (%a0) /* write (very) last 2nd word */
262
263 movem.l (%sp), %d2-%d7/%a2-%a6
264 lea.l (44, %sp), %sp /* restore registers */
265 rts
266.yuv_end:
267 .size lcd_write_yuv420_lines, .yuv_end - lcd_write_yuv420_lines
268
269
270/* begin lcd_write_data */ 28/* begin lcd_write_data */
271 .align 2 29 .align 2
272 .global lcd_write_data 30 .global lcd_write_data
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-x5.c b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
index 266a381c40..a6a4fc0176 100644
--- a/firmware/target/coldfire/iaudio/x5/lcd-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
@@ -414,69 +414,6 @@ bool lcd_active(void)
414#endif 414#endif
415/*** update functions ***/ 415/*** update functions ***/
416 416
417/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420.
418 * y should have two lines of Y back to back, 2nd line first.
419 * c should contain the Cb and Cr data for the two lines of Y back to back.
420 * Needs EMAC set to saturated, signed integer mode.
421 */
422extern void lcd_write_yuv420_lines(const unsigned char *y,
423 const unsigned char *c, int width);
424
425/* Performance function to blit a YUV bitmap directly to the LCD
426 * src_x, src_y, width and height should be even and within the LCD's
427 * boundaries.
428 */
429void lcd_blit_yuv(unsigned char * const src[3],
430 int src_x, int src_y, int stride,
431 int x, int y, int width, int height)
432{
433 /* IRAM Y, Cb/bu, guv and Cb/rv buffers. */
434 unsigned char y_ibuf[LCD_WIDTH*2];
435 unsigned char c_ibuf[LCD_WIDTH];
436 const unsigned char *ysrc, *usrc, *vsrc;
437 const unsigned char *ysrc_max;
438
439 if (!display_on)
440 return;
441
442 width &= ~1; /* stay on the safe side */
443 height &= ~1;
444
445 lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_DIT_HORZ);
446 /* Set start position and window */
447 lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_WIDTH-1) << 8);
448
449 ysrc = src[0] + src_y * stride + src_x;
450 usrc = src[1] + (src_y * stride >> 2) + (src_x >> 1);
451 vsrc = src[2] + (src_y * stride >> 2) + (src_x >> 1);
452 ysrc_max = ysrc + height * stride;
453
454 unsigned long macsr = coldfire_get_macsr();
455 coldfire_set_macsr(EMAC_SATURATE);
456
457 do
458 {
459 lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((y + y_offset + 1) << 8) | (y + y_offset));
460 lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | (y + y_offset));
461 lcd_begin_write_gram();
462
463 memcpy(y_ibuf + width, ysrc, width);
464 memcpy(y_ibuf, ysrc + stride, width);
465 memcpy(c_ibuf, usrc, width >> 1);
466 memcpy(c_ibuf + (width >> 1), vsrc, width >> 1);
467 lcd_write_yuv420_lines(y_ibuf, c_ibuf, width >> 1);
468
469 y += 2;
470 ysrc += 2 * stride;
471 usrc += stride >> 1;
472 vsrc += stride >> 1;
473 }
474 while (ysrc < ysrc_max);
475
476 coldfire_set_macsr(macsr);
477} /* lcd_yuv_blit */
478
479
480/* Update the display. 417/* Update the display.
481 This must be called after all other LCD functions that change the 418 This must be called after all other LCD functions that change the
482 lcd frame buffer. */ 419 lcd frame buffer. */