From 1bbd58e2d8e4bf9c9942c5b70ff4e480a6fc56f2 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Sun, 8 Jul 2007 13:02:52 +0000 Subject: e200 lcd mashup: 1) Enable flipped and inverted mode. 2) Fully enable all power options so that LCD driver IC's visible display is shut down with backlight and make the Sleep option available 3) Better framebuffer copy routine in assembly that confines updates to the specified rectangle _and_ is faster than memcpy 4) Some other offhand changes out of preference. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13818 a1c6a512-1295-4272-9138-f99709370657 --- .../target/arm/sandisk/sansa-e200/lcd-as-e200.S | 89 +++++++++++++++++++++- 1 file changed, 85 insertions(+), 4 deletions(-) (limited to 'firmware/target/arm/sandisk/sansa-e200/lcd-as-e200.S') diff --git a/firmware/target/arm/sandisk/sansa-e200/lcd-as-e200.S b/firmware/target/arm/sandisk/sansa-e200/lcd-as-e200.S index 9e130cf54b..f4805fd1e1 100644 --- a/firmware/target/arm/sandisk/sansa-e200/lcd-as-e200.S +++ b/firmware/target/arm/sandisk/sansa-e200/lcd-as-e200.S @@ -20,6 +20,87 @@ #include "config.h" #include "cpu.h" +/**************************************************************************** + * void lcd_copy_buffer_rect(fb_data *dst, fb_data *src, int width, + * int height); + */ + .section .icode, "ax", %progbits + .align 2 + .global lcd_copy_buffer_rect + .type lcd_copy_buffer_rect, %function + @ r0 = dst + @ r1 = src + @ r2 = width + @ r3 = height +lcd_copy_buffer_rect: @ + stmfd sp!, { r4-r12, lr } @ save non-scratch regs + mov r5, r2 @ r5 = cached width + rsb r4, r2, #LCD_WIDTH @ r4 = LCD_WIDTH - width +10: @ copy line @ + subs r2, r5, #1 @ r2 = width - 1 + beq 40f @ finish line @ one halfword? skip to trailing copy + tst r0, #2 @ word aligned? + beq 20f @ rem copy @ yes? skip to word copy + ldrh r6, [r1], #2 @ copy leading halfword + subs r2, r2, #1 @ + strh r6, [r0], #2 @ + ble 40f @ finish line @ next line if lt or finish + @ trailing halfword if eq +20: @ rem copy @ + add r14, r2, #1 @ get remaining width mod 16 after word + @ align (rw) + and r14, r14, #0xe @ r14 = 0 (16), 2, 4, 6, 8, 10, 12, 14 + add pc, pc, r14, lsl #3 @ branch to 32-byte align + nop @ + b 30f @ rw % 16 = 0 or 1? use octword loop + nop @ + nop @ + nop @ + ldr r6, [r1], #4 @ rw % 16 = 2 or 3 + subs r2, r2, #2 @ + str r6, [r0], #4 @ + b 25f @ copy up done @ + ldmia r1!, { r6-r7 } @ rw % 16 = 4 or 5 + subs r2, r2, #4 @ + stmia r0!, { r6-r7 } @ + b 25f @ copy up done @ + ldmia r1!, { r6-r8 } @ rw % 16 = 6 or 7 + subs r2, r2, #6 @ + stmia r0!, { r6-r8 } @ + b 25f @ copy up done @ + ldmia r1!, { r6-r9 } @ rw % 16 = 8 or 9 + subs r2, r2, #8 @ + stmia r0!, { r6-r9 } @ + b 25f @ copy up done @ + ldmia r1!, { r6-r10 } @ rw % 16 = 10 or 11 + subs r2, r2, #10 @ + stmia r0!, { r6-r10 } @ + b 25f @ copy up done @ + ldmia r1!, { r6-r11 } @ rw % 16 = 12 or 13 + subs r2, r2, #12 @ + stmia r0!, { r6-r11 } @ + b 25f @ copy up done @ + ldmia r1!, { r6-r12 } @ rw % 16 = 14 or 15 + subs r2, r2, #14 @ + stmia r0!, { r6-r12 } @ +25: @ copy up done @ + ble 40f @ finish line @ no 32-byte segments remaining? +30: @ octword loop @ copy 16 pixels per loop + ldmia r1!, { r6-r12, r14 } @ + subs r2, r2, #16 @ + stmia r0!, { r6-r12, r14 } @ + bgt 30b @ octword loop @ +40: @ finish line @ + ldreqh r6, [r1], #2 @ finish last halfword if eq ... + add r1, r1, r4, lsl #1 @ + streqh r6, [r0], #2 @ ... + add r0, r0, r4, lsl #1 @ + subs r3, r3, #1 @ next line + bgt 10b @ copy line @ + ldmfd sp!, { r4-r12, pc } @ restore regs and return + .size lcd_copy_buffer_rect, .-lcd_copy_buffer_rect + + /**************************************************************************** * void lcd_write_yuv_420_lines(fb_data *dst, * unsigned char chroma_buf[LCD_HEIGHT/2*3], @@ -45,8 +126,8 @@ lcd_write_yuv420_lines: @ r2 = yuv_src @ r3 = width @ [sp] = stride - stmdb sp!, { r4-r12, lr } @ save non-scratch - stmdb sp!, { r0, r3 } @ save dst and width + stmfd sp!, { r4-r12, lr } @ save non-scratch + stmfd sp!, { r0, r3 } @ save dst and width mov r14, #74 @ r14 = Y factor ldmia r2, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p @ r5 = yuv_src[1] = Cb_p @@ -140,7 +221,7 @@ lcd_write_yuv420_lines: bgt 10b @ loop line 1 @ @ do second line @ - ldmia sp!, { r0, r3 } @ pop dst and width + ldmfd sp!, { r0, r3 } @ pop dst and width sub r0, r0, #2 @ set dst to start of next line sub r1, r1, r3, asl #1 @ rewind chroma pointer... ldr r2, [sp, #40] @ r2 = stride @@ -218,5 +299,5 @@ lcd_write_yuv420_lines: subs r3, r3, #2 @ bgt 20b @ loop line 2 @ @ - ldmia sp!, { r4-r12, pc } @ restore registers and return + ldmfd sp!, { r4-r12, pc } @ restore registers and return .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines -- cgit v1.2.3