summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2006-08-15 23:55:31 +0000
committerMichael Sevakis <jethead71@rockbox.org>2006-08-15 23:55:31 +0000
commit013ab3dd3d49059a4896bce4498a48b91ade2bdc (patch)
treeaf9809336630232364c75dbdf352531934be5fbf
parent400ab9f8ee95046465bd2a334b0a0fec6dbcaa03 (diff)
downloadrockbox-013ab3dd3d49059a4896bce4498a48b91ade2bdc.tar.gz
rockbox-013ab3dd3d49059a4896bce4498a48b91ade2bdc.zip
Added assembly lcd_yuv_blit for iAudio X5 and misc. display related changes
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10599 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/coldfire/iaudio/x5/lcd-as-x5.S334
-rwxr-xr-xfirmware/target/coldfire/iaudio/x5/lcd-x5.c135
2 files changed, 364 insertions, 105 deletions
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
index 323710cc57..1a527bb8f3 100644
--- a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
+++ b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
@@ -23,10 +23,342 @@
23 23
24 .section .icode,"ax",@progbits 24 .section .icode,"ax",@progbits
25 25
26/* begin lcd_write_yuv420_lines
27 *
28 * See http://en.wikipedia.org/wiki/YCbCr
29 * ITU-R BT.601 (formerly CCIR 601):
30 * |Y'| | 0.299000 0.587000 0.114000| |R|
31 * |Pb| = |-0.168736 -0.331264 0.500000| |G| or 0.564334*(B - Y')
32 * |Pr| | 0.500000 -0.418688 0.081312| |B| or 0.713267*(R - Y')
33 * Scaled, normalized and rounded:
34 * |Y'| | 65 129 25| |R| + 16 : 16->235
35 * |Cb| = |-38 -74 112| |G| + 128 : 16->240
36 * |Cr| |112 -94 -18| |B| + 128 : 16->240
37 *
38 * The inverse:
39 * |R| |1.000000 -0.000001 1.402000| |Y'|
40 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
41 * |B| |1.000000 1.772000 0.000000| |Pr|
42 * Scaled, normalized, rounded and tweaked to yield RGB 666:
43 * |R| |74 0 102| |Y' - 16| / 256
44 * |G| = |74 -25 -52| |Cb - 128| / 256
45 * |B| |74 129 0| |Cr - 128| / 256
46 */
47 .align 2
48 .global lcd_write_yuv420_lines
49 .type lcd_write_yuv420_lines,@function
50lcd_write_yuv420_lines:
51 lea.l (-40,%sp),%sp /* free up some registers */
52 movem.l %d2-%d7/%a2-%a5,(%sp)
53
54 lea.l 0xf0008002,%a0 /* LCD data port */
55 move.l (40+4,%sp),%a1 /* Y data */
56 move.l (40+8,%sp),%a2 /* Cb data */
57 move.l (40+12,%sp),%a3 /* guv storage */
58 move.l (40+16,%sp),%a4 /* Cr data */
59 move.l (40+20,%sp),%d0 /* width */
60 lea.l (%a1,%d0.l),%a5 /* end address */
61
62.yuv_line_loop1:
63 /** Write first pixel **/
64 clr.l %d1 /* get y component */
65 move.b (%a1)+,%d1
66 subq.l #8,%d1
67 subq.l #8,%d1
68 moveq.l #74,%d6
69 muls.w %d6,%d1
70 asr.l #8,%d1
71
72 clr %d2 /* get bu component */
73 move.b (%a2),%d2
74 moveq.l #-128,%d6
75 add.l %d6,%d2
76 move.l %d2,%d3 /* %d3 = cb component for guv */
77 move.w #129,%d6
78 muls.w %d6,%d2
79 asr.l #8,%d2
80 move.b %d2,(%a2)+ /* save bu for next line */
81
82 moveq.l #-25,%d6 /* multiply first term of guv */
83 muls.w %d6,%d3
84
85 clr %d4 /* get rv component */
86 move.b (%a4),%d4
87 moveq.l #-128,%d6
88 add.l %d6,%d4
89 move.l %d4,%d7 /* %d7 = cr component for guv */
90 moveq.l #102,%d6
91 muls.w %d6,%d4
92 asr.l #8,%d4
93 move.b %d4,(%a4)+ /* save rv for next line */
94
95 moveq.l #-52,%d6 /* multiply second term of guv */
96 muls.w %d6,%d7
97 add.l %d7,%d3
98 asr.l #8,%d3
99 move.b %d3,(%a3)+ /* save guv for next line */
100 /* : %d1 = Y, %d2 = bu, %d3 = guv, %d4 = rv */
101
102 move.l %d1,%d5 /* get r */
103 add.l %d4,%d5
104 move.l %d1,%d6 /* get g */
105 add.l %d3,%d6
106 move.l %d1,%d7 /* get b */
107 add.l %d2,%d7
108
109 move.l %d7,%d1 /* is clamping needed? */
110 or.l %d6,%d1
111 or.l %d5,%d1
112 asr.l #6,%d1
113 beq.b .yuv_no_clamp1 /* values in range: skip clamping */
114 bpl.b .yuv_r63_test1 /* no negative values: skip to high bounds checks */
115.yuv_r0_test1:
116 clr.l %d1 /* check for any values < 0 */
117 cmp.l %d1,%d5
118 bgt.b .yuv_g0_test1
119 clr.l %d5
120.yuv_g0_test1:
121 cmp.l %d1,%d6
122 bgt.b .yuv_b0_test1
123 clr.l %d6
124.yuv_b0_test1:
125 cmp.l %d1,%d7
126 bgt.b .yuv_r63_test1
127 clr.l %d7
128.yuv_r63_test1: /* check for any values > 63 */
129 moveq.l #63,%d1
130 cmp.l %d1,%d5
131 blt.b .yuv_g63_test1
132 move.l %d1,%d5
133.yuv_g63_test1:
134 cmp.l %d1,%d6
135 blt.b .yuv_b63_test1
136 move.l %d1,%d6
137.yuv_b63_test1:
138 cmp.l %d1,%d7
139 blt.b .yuv_no_clamp1
140 move.l %d1,%d7
141.yuv_no_clamp1:
142 /* : %d5 = R, %d6 = G, %d7 = B */
143
144 move.l %d6,%d1 /* save g for lower 9 bits */
145 lsl.l #3,%d5 /* R << 3 */
146 lsr.l #3,%d1 /* G >> 3 */
147 or.l %d5,%d1
148 move.w %d1,(%a0) /* |00000000|000000000|0000000r|rrrrrggg| */
149 lsl.l #6,%d6 /* B << 6 */
150 or.l %d6,%d7 /* |00000000|000000000|0000gggg|ggbbbbbb| */
151 move.w %d7,(%a0)
152
153 /** Write second pixel **/
154 clr %d1
155 move.b (%a1)+,%d1 /* get y component */
156 subq.l #8,%d1
157 subq.l #8,%d1
158 moveq.l #74,%d6
159 muls.w %d6,%d1
160 asr.l #8,%d1
161 /* : %d1 = Y, %d2 = bu, %d3 = guv, %d4 = rv */
162
163 /* Add Y + each chroma component (can clobber %d2-%d4 values now) */
164 add.l %d1,%d4 /* get r */
165 add.l %d1,%d3 /* get g */
166 add.l %d1,%d2 /* get b */
167
168 move.l %d2,%d1 /* is clamping needed? */
169 or.l %d3,%d1
170 or.l %d4,%d1
171 asr.l #6,%d1
172 beq.b .yuv_no_clamp2 /* values in range: skip clamping */
173 bpl.b .yuv_r63_test2 /* no negative values: skip to high bounds checks */
174.yuv_r0_test2:
175 clr.l %d1 /* check for any values < 0 */
176 cmp.l %d1,%d4
177 bgt.b .yuv_g0_test2
178 clr.l %d4
179.yuv_g0_test2:
180 cmp.l %d1,%d3
181 bgt.b .yuv_b0_test2
182 clr.l %d3
183.yuv_b0_test2:
184 cmp.l %d1,%d2
185 bgt.b .yuv_r63_test2
186 clr.l %d2
187.yuv_r63_test2: /* check for any values > 63 */
188 moveq.l #63,%d1
189 cmp.l %d1,%d4
190 blt.b .yuv_g63_test2
191 move.l %d1,%d4
192.yuv_g63_test2:
193 cmp.l %d1,%d3
194 blt.b .yuv_b63_test2
195 move.l %d1,%d3
196.yuv_b63_test2:
197 cmp.l %d1,%d2
198 blt.b .yuv_no_clamp2
199 move.l %d1,%d2
200.yuv_no_clamp2:
201 /* : %d4 = R, %d3 = G, %d2 = B */
202
203 move.l %d3,%d1 /* save g for lower 9 bits */
204 lsl.l #3,%d4 /* R << 3 */
205 lsr.l #3,%d1 /* G >> 3 */
206 or.l %d4,%d1 /* |00000000|000000000|0000000r|rrrrrggg| */
207 move.w %d1,(%a0)
208 lsl.l #6,%d3 /* G << 6 */
209 or.l %d3,%d2 /* |00000000|000000000|0000gggg|ggbbbbbb| */
210 move.w %d2,(%a0)
211
212 cmp.l %a1,%a5 /* run %a1 up to end of line */
213 bhi.w .yuv_line_loop1
214
215 /* Rewind chroma pointers */
216 move.l (40+8,%sp),%a2 /* bu data */
217 move.l (40+12,%sp),%a3 /* guv data */
218 move.l (40+16,%sp),%a4 /* rv data */
219 lea.l (%a5,%d0),%a5 /* next end address */
220
221.yuv_line_loop2:
222 clr %d1
223 move.b (%a1)+,%d1 /* get y component */
224 subq.l #8,%d1
225 subq.l #8,%d1
226 moveq.l #74,%d6
227 muls.w %d6,%d1
228 asr.l #8,%d1
229
230 move.b (%a2)+,%d2 /* read save chromas and sign extend */
231 extb.l %d2
232 move.b (%a3)+,%d3
233 extb.l %d3
234 move.b (%a4)+,%d4
235 extb.l %d4
236 /* : %d1 = Y, %d2 = bu, %d3 = guv, %d4 = rv */
237
238 move.l %d1,%d5 /* get r */
239 add.l %d4,%d5
240 move.l %d1,%d6 /* get g */
241 add.l %d3,%d6
242 move.l %d1,%d7 /* get b */
243 add.l %d2,%d7
244
245 move.l %d7,%d1 /* is clamping needed? */
246 or.l %d6,%d1
247 or.l %d5,%d1
248 asr.l #6,%d1
249 beq.b .yuv_no_clamp3 /* values in range: skip clamping */
250 bpl.b .yuv_r63_test3 /* no negative values: skip to high bounds checks */
251.yuv_r0_test3:
252 clr.l %d1 /* check for any values < 0 */
253 cmp.l %d1,%d5
254 bgt.b .yuv_g0_test3
255 clr.l %d5
256.yuv_g0_test3:
257 cmp.l %d1,%d6
258 bgt.b .yuv_b0_test3
259 clr.l %d6
260.yuv_b0_test3:
261 cmp.l %d1,%d7
262 bgt.b .yuv_r63_test3
263 clr.l %d7
264.yuv_r63_test3: /* check for any values > 63 */
265 moveq.l #63,%d1
266 cmp.l %d1,%d5
267 blt.b .yuv_g63_test3
268 move.l %d1,%d5
269.yuv_g63_test3:
270 cmp.l %d1,%d6
271 blt.b .yuv_b63_test3
272 move.l %d1,%d6
273.yuv_b63_test3:
274 cmp.l %d1,%d7
275 blt.b .yuv_no_clamp3
276 move.l %d1,%d7
277.yuv_no_clamp3:
278 /* : %d5 = R, %d6 = G, %d7 = B */
279
280 move.l %d6,%d1 /* save g for lower 9 bits */
281 lsl.l #3,%d5 /* R << 3 */
282 lsr.l #3,%d1 /* G >> 3 */
283 or.l %d5,%d1
284 move.w %d1,(%a0) /* |00000000|000000000|0000000r|rrrrrggg| */
285 lsl.l #6,%d6 /* B << 6 */
286 or.l %d6,%d7 /* |00000000|000000000|0000gggg|ggbbbbbb| */
287 move.w %d7,(%a0)
288
289 /** Write second pixel **/
290 clr %d1
291 move.b (%a1)+,%d1 /* get y component */
292 subq.l #8,%d1
293 subq.l #8,%d1
294 moveq.l #74,%d6
295 muls.w %d6,%d1
296 asr.l #8,%d1
297 /* : %d1 = Y, %d2 = bu, %d3 = guv, %d4 = rv */
298
299 /* Add Y + each chroma component (can clobber %d2-%d4 values now) */
300 add.l %d1,%d4 /* get r */
301 add.l %d1,%d3 /* get g */
302 add.l %d1,%d2 /* get b */
303
304 move.l %d2,%d1 /* is clamping needed? */
305 or.l %d3,%d1
306 or.l %d4,%d1
307 asr.l #6,%d1
308 beq.b .yuv_no_clamp4 /* values in range: skip clamping */
309 bpl.b .yuv_r63_test4 /* no negative values: skip to high bounds checks */
310.yuv_r0_test4:
311 clr.l %d1 /* check for any values < 0 */
312 cmp.l %d1,%d4
313 bgt.b .yuv_g0_test4
314 clr.l %d4
315.yuv_g0_test4:
316 cmp.l %d1,%d3
317 bgt.b .yuv_b0_test4
318 clr.l %d3
319.yuv_b0_test4:
320 cmp.l %d1,%d2
321 bgt.b .yuv_r63_test4
322 clr.l %d2
323.yuv_r63_test4: /* check for any values > 63 */
324 moveq.l #63,%d1
325 cmp.l %d1,%d4
326 blt.b .yuv_g63_test4
327 move.l %d1,%d4
328.yuv_g63_test4:
329 cmp.l %d1,%d3
330 blt.b .yuv_b63_test4
331 move.l %d1,%d3
332.yuv_b63_test4:
333 cmp.l %d1,%d2
334 blt.b .yuv_no_clamp4
335 move.l %d1,%d2
336.yuv_no_clamp4:
337 /* : %d4 = R, %d3 = G, %d2 = B */
338
339 move.l %d3,%d1 /* save g for lower 9 bits */
340 lsl.l #3,%d4 /* R << 3 */
341 lsr.l #3,%d1 /* G >> 3 */
342 or.l %d4,%d1 /* |00000000|000000000|0000000r|rrrrrggg| */
343 move.w %d1,(%a0)
344 lsl.l #6,%d3 /* G << 6 */
345 or.l %d3,%d2 /* |00000000|000000000|0000gggg|ggbbbbbb| */
346 move.w %d2,(%a0)
347
348 cmp.l %a1,%a5 /* run %a0 up to end of line */
349 bhi.w .yuv_line_loop2
350
351 movem.l (%sp),%d2-%d7/%a2-%a5
352 lea.l (40,%sp),%sp /* restore registers */
353
354 rts
355/* end lcd_write_yuv420_lines */
356
357
358/* begin lcd_write_data */
26 .align 2 359 .align 2
27 .global lcd_write_data 360 .global lcd_write_data
28 .type lcd_write_data,@function 361 .type lcd_write_data,@function
29
30lcd_write_data: 362lcd_write_data:
31 move.l (4,%sp),%a0 /* data pointer */ 363 move.l (4,%sp),%a0 /* data pointer */
32 move.l (8,%sp),%d0 /* length in words */ 364 move.l (8,%sp),%d0 /* length in words */
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-x5.c b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
index 240b1db586..e1fe23a442 100755
--- a/firmware/target/coldfire/iaudio/x5/lcd-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
@@ -100,25 +100,6 @@ static inline void lcd_begin_write_gram(void)
100 LCD_CMD = R_WRITE_DATA_2_GRAM << 1; 100 LCD_CMD = R_WRITE_DATA_2_GRAM << 1;
101} 101}
102 102
103static inline void lcd_write_one(unsigned short px)
104{
105 unsigned short pxsr = px >> 8;
106 LCD_DATA = pxsr + (pxsr & 0x1F8);
107 LCD_DATA = px << 1;
108}
109
110/* Write two pixels to gram from a long */
111/* called very frequently - inline! */
112static inline void lcd_write_two(unsigned long px2)
113{
114 unsigned short px2sr = px2 >> 24;
115 LCD_DATA = px2sr + (px2sr & 0x1F8);
116 LCD_DATA = px2 >> 15;
117 px2sr = px2 >> 8;
118 LCD_DATA = px2sr + (px2sr & 0x1F8);
119 LCD_DATA = px2 << 1;
120}
121
122/*** hardware configuration ***/ 103/*** hardware configuration ***/
123 104
124int lcd_default_contrast(void) 105int lcd_default_contrast(void)
@@ -423,45 +404,38 @@ void lcd_blit(const fb_data* data, int x, int by, int width,
423 /*if(display_on)*/ 404 /*if(display_on)*/
424} 405}
425 406
426/* Performance function to blit a YUV bitmap directly to the LCD */ 407/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420.
427/* Assumes YCrCb 4:2:0. */ 408 * y should have two lines of Y back to back.
428/* 409 * bu and rv should contain the Cb and Cr data for the two lines of Y.
429 See http://en.wikipedia.org/wiki/YCbCr 410 * Stores bu, guv and rv in repective buffers for use in second line.
430 ITU-R BT.601 (formerly CCIR 601): 411 */
431 |Y'| | 0.299000 0.587000 0.114000| |R| 412extern void lcd_write_yuv420_lines(const unsigned char *y,
432 |Pb| = |-0.168736 -0.331264 0.500000| |G| or 0.564334 * (B - Y') 413 unsigned char *bu, unsigned char *guv, unsigned char *rv,
433 |Pr| | 0.500000 -0.418688 0.081312| |B| or 0.713267 * (R - Y') 414 int width);
434 Scaled, normalized and rounded: 415
435 |Y'| | 65 129 25| |R| + 16 : 16->235 416/* Performance function to blit a YUV bitmap directly to the LCD
436 |Cb| = |-38 -74 112| |G| + 128 : 16->240 417 * src_x, src_y, width and height should be even and within the LCD's
437 |Cr| |112 -94 -18| |B| + 128 : 16->240 418 * boundaries.
438 419 */
439 The inverse:
440 |R| |1.000000 -0.000001 1.402000| |Y'|
441 |G| = |1.000000 -0.334136 -0.714136| |Pb|
442 |B| |1.000000 1.772000 0.000000| |Pr|
443 Scaled, normalized, rounded and tweaked to yield RGB 666:
444 |R| |298 0 409| |Y' - 16| / 1024
445 |G| = |298 -100 -208| |Cb - 128| / 1024
446 |B| |298 516 0| |Cr - 128| / 1024
447*/
448void lcd_yuv_blit(unsigned char * const [3], int, int, int,
449 int, int, int, int) ICODE_ATTR;
450void lcd_yuv_blit(unsigned char * const src[3], 420void lcd_yuv_blit(unsigned char * const src[3],
451 int src_x, int src_y, int stride, 421 int src_x, int src_y, int stride,
452 int x, int y, int width, int height) 422 int x, int y, int width, int height)
453{ 423{
424 /* IRAM Y, Cb/bu, guv and Cb/rv buffers. */
425 unsigned char y_ibuf[LCD_WIDTH*2];
426 unsigned char bu_ibuf[LCD_WIDTH/2];
427 unsigned char guv_ibuf[LCD_WIDTH/2];
428 unsigned char rv_ibuf[LCD_WIDTH/2];
454 const unsigned char *ysrc, *usrc, *vsrc; 429 const unsigned char *ysrc, *usrc, *vsrc;
455 int uv_stepper, uv_step, y_end; 430 const unsigned char *ysrc_max;
456 431
457 if (!display_on) 432 if (!display_on)
458 return; 433 return;
459 434
460 width = (width + 1) & ~1; 435 width = (width + 1) & ~1;
461 height = (height + 1) & ~1; 436 height = (height + 1) & ~1;
462 y_end = y + height;
463 437
464 /* Set start position and window */ 438 /* Set start position and window */
465 lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | 439 lcd_write_reg(R_RAM_ADDR_SET, (x << 8) |
466 (((y + roll_offset) & 127) + y_offset)); 440 (((y + roll_offset) & 127) + y_offset));
467 lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x); 441 lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x);
@@ -471,72 +445,26 @@ void lcd_yuv_blit(unsigned char * const src[3],
471 ysrc = src[0] + src_y*stride + src_x; 445 ysrc = src[0] + src_y*stride + src_x;
472 usrc = src[1] + (src_y*stride >> 2) + (src_x >> 1); 446 usrc = src[1] + (src_y*stride >> 2) + (src_x >> 1);
473 vsrc = src[2] + (usrc - src[1]); 447 vsrc = src[2] + (usrc - src[1]);
474 448 ysrc_max = ysrc + height*stride;
475 stride = stride - width; /* Use end of current line->start of next */
476 uv_stepper = (stride >> 1) - (width >> 1);
477 uv_step = uv_stepper - (stride >> 1);
478 449
479 do 450 do
480 { 451 {
481 const unsigned char *ysrc_end = ysrc + width; 452 memcpy(y_ibuf, ysrc, width);
482 453 memcpy(&y_ibuf[width], &ysrc[stride], width);
483 do 454 memcpy(bu_ibuf, usrc, width >> 1);
484 { 455 memcpy(rv_ibuf, vsrc, width >> 1);
485 int lum, cb, cr; 456 lcd_write_yuv420_lines(y_ibuf, bu_ibuf, guv_ibuf, rv_ibuf, width);
486 int rv, guv, bu; 457 ysrc += stride << 1;
487 int r, g, b; 458 usrc += stride >> 1;
488 459 vsrc += stride >> 1;
489 lum = 298* *ysrc++ - 4768; /* 298*16 */
490 cb = *usrc++ - 128;
491 cr = *vsrc++ - 128;
492 bu = 516*cb;
493 guv = -100*cb - 208*cr;
494 rv = 409*cr;
495
496 r = (lum + rv) >> 10;
497 g = (lum + guv) >> 10;
498 b = (lum + bu) >> 10;
499
500 if ((unsigned)r > 63)
501 r = (r < 0) ? 0 : 63;
502 if ((unsigned)g > 63)
503 g = (g < 0) ? 0 : 63;
504 if ((unsigned)b > 63)
505 b = (b < 0) ? 0 : 63;
506
507 LCD_DATA = (r << 3) | (g >> 3);
508 LCD_DATA = (g << 6) | b;
509
510 lum = 298* *ysrc++ - 4768; /* 298*16 */
511 r = (lum + rv) >> 10;
512 g = (lum + guv) >> 10;
513 b = (lum + bu) >> 10;
514
515 if ((unsigned)r > 63)
516 r = (r < 0) ? 0 : 63;
517 if ((unsigned)g > 63)
518 g = (g < 0) ? 0 : 63;
519 if ((unsigned)b > 63)
520 b = (b < 0) ? 0 : 63;
521
522 LCD_DATA = (r << 3) | (g >> 3);
523 LCD_DATA = (g << 6) | b;
524 }
525 while (ysrc < ysrc_end);
526
527 usrc += uv_step;
528 vsrc += uv_step;
529 uv_step = uv_stepper - uv_step;
530
531 ysrc += stride;
532 } 460 }
533 while (++y < y_end); 461 while (ysrc < ysrc_max);
534} /* lcd_yuv_blit */ 462} /* lcd_yuv_blit */
535 463
464
536/* Update the display. 465/* Update the display.
537 This must be called after all other LCD functions that change the 466 This must be called after all other LCD functions that change the
538 lcd frame buffer. */ 467 lcd frame buffer. */
539void lcd_update(void) ICODE_ATTR;
540void lcd_update(void) 468void lcd_update(void)
541{ 469{
542 if (!display_on) 470 if (!display_on)
@@ -554,7 +482,6 @@ void lcd_update(void)
554} /* lcd_update */ 482} /* lcd_update */
555 483
556/* Update a fraction of the display. */ 484/* Update a fraction of the display. */
557void lcd_update_rect(int, int, int, int) ICODE_ATTR;
558void lcd_update_rect(int x, int y, int width, int height) 485void lcd_update_rect(int x, int y, int width, int height)
559{ 486{
560 int ymax; 487 int ymax;