diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/ipod/lcd-gray.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/firmware/target/arm/ipod/lcd-gray.c b/firmware/target/arm/ipod/lcd-gray.c index 65fa2a779e..c7f4074c0b 100644 --- a/firmware/target/arm/ipod/lcd-gray.c +++ b/firmware/target/arm/ipod/lcd-gray.c | |||
@@ -299,6 +299,123 @@ void lcd_blit(const unsigned char* data, int bx, int y, int bwidth, | |||
299 | } | 299 | } |
300 | } | 300 | } |
301 | 301 | ||
302 | /* Performance function that works with an external buffer | ||
303 | note that bx and bwidth are in 8-pixel units! */ | ||
304 | void lcd_grey_phase_blit(const struct grey_data *data, int bx, int y, | ||
305 | int bwidth, int height, int stride) | ||
306 | { | ||
307 | const struct grey_data *addr; | ||
308 | int width; | ||
309 | |||
310 | while (height--) { | ||
311 | lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx); | ||
312 | lcd_prepare_cmd(R_RAM_DATA); | ||
313 | |||
314 | addr = data; | ||
315 | width = bwidth; | ||
316 | asm volatile ( | ||
317 | "10: \n" | ||
318 | "ldmia %[addr]!, {r0-r3} \n" /* r0 = v1p1v0p0 ... */ | ||
319 | #ifdef IPOD_MINI2G | ||
320 | "mov r5, #0x7600 \n" | ||
321 | #else | ||
322 | "mov r5, #0 \n" | ||
323 | #endif | ||
324 | |||
325 | "and r4, r0, %[mask] \n" /* r4 = --p1--p0 */ | ||
326 | "and r0, %[mask], r0, lsr #8 \n" /* r0 = --v1--v0 */ | ||
327 | |||
328 | "tst r4, #0x80 \n" | ||
329 | "orreq r5, r5, #0xc0 \n" | ||
330 | "tst r4, #0x800000 \n" | ||
331 | "orreq r5, r5, #0x30 \n" | ||
332 | "bic r4, r4, %[clbt] \n" | ||
333 | |||
334 | "add r4, r0, r4 \n" /* p0 += v0; p1 += v1; */ | ||
335 | "strb r4, [%[addr], #-16] \n" | ||
336 | "mov r4, r4, lsr #16 \n" | ||
337 | "strb r4, [%[addr], #-14] \n" | ||
338 | |||
339 | "and r4, r1, %[mask] \n" | ||
340 | "and r1, %[mask], r1, lsr #8 \n" | ||
341 | |||
342 | "tst r4, #0x80 \n" | ||
343 | "orreq r5, r5, #0x0c \n" | ||
344 | "tst r4, #0x800000 \n" | ||
345 | "orreq r5, r5, #0x03 \n" | ||
346 | "bic r4, r4, %[clbt] \n" | ||
347 | |||
348 | "add r4, r1, r4 \n" | ||
349 | "strb r4, [%[addr], #-12] \n" | ||
350 | "mov r4, r4, lsr #16 \n" | ||
351 | "strb r4, [%[addr], #-10] \n" | ||
352 | |||
353 | #ifdef IPOD_MINI2G | ||
354 | "mov r5, r5, lsl #8 \n" | ||
355 | #else | ||
356 | "1: \n" | ||
357 | "ldr r4, [%[lcdb]] \n" | ||
358 | "tst r4, #0x8000 \n" | ||
359 | "bne 1b \n" | ||
360 | |||
361 | "str r5, [%[lcdb], #0x10] \n" | ||
362 | "mov r5, #0 \n" | ||
363 | #endif | ||
364 | |||
365 | "and r4, r2, %[mask] \n" | ||
366 | "and r2, %[mask], r2, lsr #8 \n" | ||
367 | |||
368 | "tst r4, #0x80 \n" | ||
369 | "orreq r5, r5, #0xc0 \n" | ||
370 | "tst r4, #0x800000 \n" | ||
371 | "orreq r5, r5, #0x30 \n" | ||
372 | "bic r4, r4, %[clbt] \n" | ||
373 | |||
374 | "add r4, r2, r4 \n" | ||
375 | "strb r4, [%[addr], #-8] \n" | ||
376 | "mov r4, r4, lsr #16 \n" | ||
377 | "strb r4, [%[addr], #-6] \n" | ||
378 | |||
379 | "and r4, r3, %[mask] \n" | ||
380 | "and r3, %[mask], r3, lsr #8 \n" | ||
381 | |||
382 | "tst r4, #0x80 \n" | ||
383 | "orreq r5, r5, #0x0c \n" | ||
384 | "tst r4, #0x800000 \n" | ||
385 | "orreq r5, r5, #0x03 \n" | ||
386 | "bic r4, r4, %[clbt] \n" | ||
387 | |||
388 | "add r4, r3, r4 \n" | ||
389 | "strb r4, [%[addr], #-4] \n" | ||
390 | "mov r4, r4, lsr #16 \n" | ||
391 | "strb r4, [%[addr], #-2] \n" | ||
392 | |||
393 | "1: \n" | ||
394 | "ldr r4, [%[lcdb]] \n" | ||
395 | "tst r4, #0x8000 \n" | ||
396 | "bne 1b \n" | ||
397 | #ifdef IPOD_MINI2G | ||
398 | "str r5, [%[lcdb], #0x08] \n" | ||
399 | #else | ||
400 | "str r5, [%[lcdb], #0x10] \n" | ||
401 | #endif | ||
402 | |||
403 | "subs %[wdth], %[wdth], #1 \n" | ||
404 | "bne 10b \n" | ||
405 | : /* outputs */ | ||
406 | [addr]"+r"(addr), | ||
407 | [wdth]"+r"(width) | ||
408 | : /* inputs */ | ||
409 | [mask]"r"(0x00ff00ff), | ||
410 | [clbt]"r"(0x00800080), | ||
411 | [lcdb]"r"(LCD1_BASE) | ||
412 | : /* clobbers */ | ||
413 | "r0", "r1", "r2", "r3", "r4", "r5" | ||
414 | ); | ||
415 | data += stride; | ||
416 | } | ||
417 | } | ||
418 | |||
302 | void lcd_update_rect(int x, int y, int width, int height) | 419 | void lcd_update_rect(int x, int y, int width, int height) |
303 | { | 420 | { |
304 | int xmax, ymax; | 421 | int xmax, ymax; |