diff options
Diffstat (limited to 'firmware/target/arm/sandisk/sansa-e200/lcd-as-e200.S')
-rw-r--r-- | firmware/target/arm/sandisk/sansa-e200/lcd-as-e200.S | 89 |
1 files changed, 85 insertions, 4 deletions
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 | |||
@@ -21,6 +21,87 @@ | |||
21 | #include "cpu.h" | 21 | #include "cpu.h" |
22 | 22 | ||
23 | /**************************************************************************** | 23 | /**************************************************************************** |
24 | * void lcd_copy_buffer_rect(fb_data *dst, fb_data *src, int width, | ||
25 | * int height); | ||
26 | */ | ||
27 | .section .icode, "ax", %progbits | ||
28 | .align 2 | ||
29 | .global lcd_copy_buffer_rect | ||
30 | .type lcd_copy_buffer_rect, %function | ||
31 | @ r0 = dst | ||
32 | @ r1 = src | ||
33 | @ r2 = width | ||
34 | @ r3 = height | ||
35 | lcd_copy_buffer_rect: @ | ||
36 | stmfd sp!, { r4-r12, lr } @ save non-scratch regs | ||
37 | mov r5, r2 @ r5 = cached width | ||
38 | rsb r4, r2, #LCD_WIDTH @ r4 = LCD_WIDTH - width | ||
39 | 10: @ copy line @ | ||
40 | subs r2, r5, #1 @ r2 = width - 1 | ||
41 | beq 40f @ finish line @ one halfword? skip to trailing copy | ||
42 | tst r0, #2 @ word aligned? | ||
43 | beq 20f @ rem copy @ yes? skip to word copy | ||
44 | ldrh r6, [r1], #2 @ copy leading halfword | ||
45 | subs r2, r2, #1 @ | ||
46 | strh r6, [r0], #2 @ | ||
47 | ble 40f @ finish line @ next line if lt or finish | ||
48 | @ trailing halfword if eq | ||
49 | 20: @ rem copy @ | ||
50 | add r14, r2, #1 @ get remaining width mod 16 after word | ||
51 | @ align (rw) | ||
52 | and r14, r14, #0xe @ r14 = 0 (16), 2, 4, 6, 8, 10, 12, 14 | ||
53 | add pc, pc, r14, lsl #3 @ branch to 32-byte align | ||
54 | nop @ | ||
55 | b 30f @ rw % 16 = 0 or 1? use octword loop | ||
56 | nop @ | ||
57 | nop @ | ||
58 | nop @ | ||
59 | ldr r6, [r1], #4 @ rw % 16 = 2 or 3 | ||
60 | subs r2, r2, #2 @ | ||
61 | str r6, [r0], #4 @ | ||
62 | b 25f @ copy up done @ | ||
63 | ldmia r1!, { r6-r7 } @ rw % 16 = 4 or 5 | ||
64 | subs r2, r2, #4 @ | ||
65 | stmia r0!, { r6-r7 } @ | ||
66 | b 25f @ copy up done @ | ||
67 | ldmia r1!, { r6-r8 } @ rw % 16 = 6 or 7 | ||
68 | subs r2, r2, #6 @ | ||
69 | stmia r0!, { r6-r8 } @ | ||
70 | b 25f @ copy up done @ | ||
71 | ldmia r1!, { r6-r9 } @ rw % 16 = 8 or 9 | ||
72 | subs r2, r2, #8 @ | ||
73 | stmia r0!, { r6-r9 } @ | ||
74 | b 25f @ copy up done @ | ||
75 | ldmia r1!, { r6-r10 } @ rw % 16 = 10 or 11 | ||
76 | subs r2, r2, #10 @ | ||
77 | stmia r0!, { r6-r10 } @ | ||
78 | b 25f @ copy up done @ | ||
79 | ldmia r1!, { r6-r11 } @ rw % 16 = 12 or 13 | ||
80 | subs r2, r2, #12 @ | ||
81 | stmia r0!, { r6-r11 } @ | ||
82 | b 25f @ copy up done @ | ||
83 | ldmia r1!, { r6-r12 } @ rw % 16 = 14 or 15 | ||
84 | subs r2, r2, #14 @ | ||
85 | stmia r0!, { r6-r12 } @ | ||
86 | 25: @ copy up done @ | ||
87 | ble 40f @ finish line @ no 32-byte segments remaining? | ||
88 | 30: @ octword loop @ copy 16 pixels per loop | ||
89 | ldmia r1!, { r6-r12, r14 } @ | ||
90 | subs r2, r2, #16 @ | ||
91 | stmia r0!, { r6-r12, r14 } @ | ||
92 | bgt 30b @ octword loop @ | ||
93 | 40: @ finish line @ | ||
94 | ldreqh r6, [r1], #2 @ finish last halfword if eq ... | ||
95 | add r1, r1, r4, lsl #1 @ | ||
96 | streqh r6, [r0], #2 @ ... | ||
97 | add r0, r0, r4, lsl #1 @ | ||
98 | subs r3, r3, #1 @ next line | ||
99 | bgt 10b @ copy line @ | ||
100 | ldmfd sp!, { r4-r12, pc } @ restore regs and return | ||
101 | .size lcd_copy_buffer_rect, .-lcd_copy_buffer_rect | ||
102 | |||
103 | |||
104 | /**************************************************************************** | ||
24 | * void lcd_write_yuv_420_lines(fb_data *dst, | 105 | * void lcd_write_yuv_420_lines(fb_data *dst, |
25 | * unsigned char chroma_buf[LCD_HEIGHT/2*3], | 106 | * unsigned char chroma_buf[LCD_HEIGHT/2*3], |
26 | unsigned char const * const src[3], | 107 | unsigned char const * const src[3], |
@@ -45,8 +126,8 @@ lcd_write_yuv420_lines: | |||
45 | @ r2 = yuv_src | 126 | @ r2 = yuv_src |
46 | @ r3 = width | 127 | @ r3 = width |
47 | @ [sp] = stride | 128 | @ [sp] = stride |
48 | stmdb sp!, { r4-r12, lr } @ save non-scratch | 129 | stmfd sp!, { r4-r12, lr } @ save non-scratch |
49 | stmdb sp!, { r0, r3 } @ save dst and width | 130 | stmfd sp!, { r0, r3 } @ save dst and width |
50 | mov r14, #74 @ r14 = Y factor | 131 | mov r14, #74 @ r14 = Y factor |
51 | ldmia r2, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p | 132 | ldmia r2, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p |
52 | @ r5 = yuv_src[1] = Cb_p | 133 | @ r5 = yuv_src[1] = Cb_p |
@@ -140,7 +221,7 @@ lcd_write_yuv420_lines: | |||
140 | bgt 10b @ loop line 1 @ | 221 | bgt 10b @ loop line 1 @ |
141 | @ do second line | 222 | @ do second line |
142 | @ | 223 | @ |
143 | ldmia sp!, { r0, r3 } @ pop dst and width | 224 | ldmfd sp!, { r0, r3 } @ pop dst and width |
144 | sub r0, r0, #2 @ set dst to start of next line | 225 | sub r0, r0, #2 @ set dst to start of next line |
145 | sub r1, r1, r3, asl #1 @ rewind chroma pointer... | 226 | sub r1, r1, r3, asl #1 @ rewind chroma pointer... |
146 | ldr r2, [sp, #40] @ r2 = stride | 227 | ldr r2, [sp, #40] @ r2 = stride |
@@ -218,5 +299,5 @@ lcd_write_yuv420_lines: | |||
218 | subs r3, r3, #2 @ | 299 | subs r3, r3, #2 @ |
219 | bgt 20b @ loop line 2 @ | 300 | bgt 20b @ loop line 2 @ |
220 | @ | 301 | @ |
221 | ldmia sp!, { r4-r12, pc } @ restore registers and return | 302 | ldmfd sp!, { r4-r12, pc } @ restore registers and return |
222 | .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines | 303 | .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines |