summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2008-01-09 23:48:26 +0000
committerJens Arnold <amiconn@rockbox.org>2008-01-09 23:48:26 +0000
commit6a56c14e17f6ba113ec0d4d40e75bffd61b293cc (patch)
tree64bcdd8d5d4afa2ca6dd1aa0976cdafa9a346b26 /firmware/target/coldfire
parent75380fd27d175bab1818ef35a9100e74fc6a461b (diff)
downloadrockbox-6a56c14e17f6ba113ec0d4d40e75bffd61b293cc.tar.gz
rockbox-6a56c14e17f6ba113ec0d4d40e75bffd61b293cc.zip
Greyscale library: Changed the internal data format once more (separated pixel values and phases), allowing for further optimisation of drawing, scrolling etc. * Optimised grey phase blitting in the core reduces CPU load on all architectures, most significantly on coldfire. Previous version was too slow to keep up at 45MHz, leading to unwanted graininess (update frequency was halved). Also fixed screendump on 2bpp targets with vertical pixel packing.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16043 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/coldfire')
-rw-r--r--firmware/target/coldfire/iaudio/m5/lcd-as-m5.S189
-rw-r--r--firmware/target/coldfire/iaudio/m5/lcd-m5.c12
-rw-r--r--firmware/target/coldfire/iriver/h100/lcd-as-h100.S189
-rw-r--r--firmware/target/coldfire/iriver/h100/lcd-h100.c12
4 files changed, 294 insertions, 108 deletions
diff --git a/firmware/target/coldfire/iaudio/m5/lcd-as-m5.S b/firmware/target/coldfire/iaudio/m5/lcd-as-m5.S
index 7e89815ec8..0ec98e4589 100644
--- a/firmware/target/coldfire/iaudio/m5/lcd-as-m5.S
+++ b/firmware/target/coldfire/iaudio/m5/lcd-as-m5.S
@@ -88,57 +88,146 @@ lcd_write_data:
88 .type lcd_grey_data,@function 88 .type lcd_grey_data,@function
89 89
90lcd_grey_data: 90lcd_grey_data:
91 lea.l (-4*4, %sp), %sp 91 lea.l (-9*4, %sp), %sp
92 movem.l %d2-%d5, (%sp) 92 movem.l %d2-%d5/%a2-%a6, (%sp) /* free some registers */
93 movem.l (4*4+4, %sp), %a0-%a1 /* Data pointer */ 93 movem.l (9*4+4, %sp), %a0-%a2 /* values, phases, length */
94 move.l %a1, %d0 /* Length */ 94 lea.l (%a1, %a2.l*4), %a2 /* end address */
95 lea 0xf0008002, %a1 /* LCD data port */ 95 lea 0xf0008002, %a3 /* LCD data port */
96 move.l #0xff00ff00, %d2 /* mask for splitting value/phase pairs */ 96
97 97 moveq.l #15, %d3
98.greyloop: 98 add.l %a1, %d3
99 movem.l (%a0), %d4-%d5 /* fetch 4 pixel phase/value pairs at once */ 99 and.l #0xfffffff0, %d3 /* first line bound */
100 /* %d4 = p0v0p1v1, %d5 = p2v2p3v3 */ 100 move.l %a2, %d1
101 move.l %d2, %d3 /* copy mask */ 101 and.l #0xfffffff0, %d1 /* last line bound */
102 and.l %d4, %d3 /* %d3 = p0--p1-- */ 102 cmp.l %d3, %d1
103 eor.l %d3, %d4 /* %d4 = --v0--v1 */ 103 bls.w .g_tloop /* no lines to copy - jump to tail loop */
104 lsr.l #8, %d3 /* %d3 = --p0--p1 */ 104 cmp.l %a1, %d0
105 105 bls.s .g_lloop /* no head blocks - jump to line loop */
106 bclr.l #23, %d3 /* Z = !(p0 & 0x80); p0 &= ~0x80; */ 106
107 seq.b %d1 /* %d1 = ........................00000000 */ 107.g_hloop:
108 lsl.l #2, %d1 /* %d1 = ......................00000000.. */ 108 move.l (%a1), %d2 /* fetch 4 pixel phases */
109 bclr.l #7, %d3 /* Z = !(p1 & 0x80); p1 &= ~0x80; */ 109
110 seq.b %d1 /* %d1 = ......................0011111111 */ 110 bclr.l #31, %d2 /* Z = !(p0 & 0x80); p0 &= ~0x80; */
111 lsl.l #2, %d1 /* %d1 = ....................0011111111.. */ 111 seq.b %d0 /* %d0 = ........................00000000 */
112 lsl.l #2, %d0 /* %d0 = ......................00000000.. */
113 bclr.l #23, %d2 /* Z = !(p1 & 0x80); p1 &= ~0x80; */
114 seq.b %d0 /* %d0 = ......................0011111111 */
115 lsl.l #2, %d0 /* %d0 = ....................0011111111.. */
116 bclr.l #15, %d2 /* Z = !(p2 & 0x80); p2 &= ~0x80; */
117 seq.b %d0 /* %d0 = ....................001122222222 */
118 lsl.l #2, %d0 /* %d0 = ..................001122222222.. */
119 bclr.l #7, %d2 /* Z = !(p3 & 0x80); p3 &= ~0x80; */
120 seq.b %d0 /* %d0 = ..................00112233333333 */
121 lsr.l #6, %d0 /* %d0 = ........................00112233 */
122 move.w %d0, (%a3) /* write pixel block */
123
124 add.l (%a0)+, %d2 /* add 4 pixel values to the phases */
125 move.l %d2, (%a1)+ /* store new phases, advance pointer */
126
127 cmp.l %a1, %d3 /* go up to first line bound */
128 bhi.s .g_hloop
129
130.g_lloop:
131 movem.l (%a1), %d2-%d5
132
133 bclr.l #31, %d2
134 seq.b %d0
135 lsl.l #2, %d0
136 bclr.l #23, %d2
137 seq.b %d0
138 lsl.l #2, %d0
139 bclr.l #15, %d2
140 seq.b %d0
141 lsl.l #2, %d0
142 bclr.l #7, %d2
143 seq.b %d0
144 lsr.l #6, %d0
145 move.w %d0, (%a3)
146
147 bclr.l #31, %d3
148 seq.b %d0
149 lsl.l #2, %d0
150 bclr.l #23, %d3
151 seq.b %d0
152 lsl.l #2, %d0
153 bclr.l #15, %d3
154 seq.b %d0
155 lsl.l #2, %d0
156 bclr.l #7, %d3
157 seq.b %d0
158 lsr.l #6, %d0
159 move.w %d0, (%a3)
112 160
113 add.l %d4, %d3 /* p0 += v0; p1 += v1; */ 161 bclr.l #31, %d4
114 move.b %d3, (2, %a0) /* store p1 */ 162 seq.b %d0
115 swap %d3 163 lsl.l #2, %d0
116 move.b %d3, (%a0) /* store p0 */ 164 bclr.l #23, %d4
117 165 seq.b %d0
118 move.l %d2, %d3 /* copy mask */ 166 lsl.l #2, %d0
119 and.l %d5, %d3 /* %d3 = p2--p3-- */ 167 bclr.l #15, %d4
120 eor.l %d3, %d5 /* %d5 = --v2--v3 */ 168 seq.b %d0
121 lsr.l #8, %d3 /* %d3 = --p2--p3 */ 169 lsl.l #2, %d0
122 170 bclr.l #7, %d4
123 bclr.l #23, %d3 /* Z = !(p2 & 0x80); p2 &= ~0x80; */ 171 seq.b %d0
124 seq.b %d1 /* %d1 = ....................001122222222 */ 172 lsr.l #6, %d0
125 lsl.l #2, %d1 /* %d1 = ..................001122222222.. */ 173 move.w %d0, (%a3)
126 bclr.l #7, %d3 /* Z = !(p3 & 0x80); p3 &= ~0x80; */ 174
127 seq.b %d1 /* %d1 = ..................00112233333333 */ 175 bclr.l #31, %d5
128 lsr.l #6, %d1 /* %d1 = ........................00112233 */ 176 seq.b %d0
129 177 lsl.l #2, %d0
130 add.l %d5, %d3 /* p2 += v2; p3 += v3; */ 178 bclr.l #23, %d5
131 move.b %d3, (6, %a0) /* store p3 */ 179 seq.b %d0
132 swap %d3 180 lsl.l #2, %d0
133 move.b %d3, (4, %a0) /* store p2 */ 181 bclr.l #15, %d5
134 182 seq.b %d0
135 move.w %d1, (%a1) /* write pixel block */ 183 lsl.l #2, %d0
136 addq.l #8, %a0 /* advance address pointer */ 184 bclr.l #7, %d5
137 subq.l #1, %d0 /* any blocks left? */ 185 seq.b %d0
138 bne.b .greyloop 186 lsr.l #6, %d0
139 187 move.w %d0, (%a3)
140 movem.l (%sp), %d2-%d5 188
141 lea.l (4*4, %sp), %sp 189 movem.l (%a0), %d0/%a4-%a6
190 lea.l (16, %a0), %a0
191 add.l %d0, %d2
192 add.l %a4, %d3
193 add.l %a5, %d4
194 add.l %a6, %d5
195 movem.l %d2-%d5, (%a1)
196 lea.l (16, %a1), %a1
197
198 cmp.l %a1, %d1 /* go up to last line bound */
199 bhi.w .g_lloop
200
201 cmp.l %a1, %a2
202 bls.s .g_no_tail
203
204.g_tloop:
205 move.l (%a1), %d2
206
207 bclr.l #31, %d2
208 seq.b %d0
209 lsl.l #2, %d0
210 bclr.l #23, %d2
211 seq.b %d0
212 lsl.l #2, %d0
213 bclr.l #15, %d2
214 seq.b %d0
215 lsl.l #2, %d0
216 bclr.l #7, %d2
217 seq.b %d0
218 lsr.l #6, %d0
219 move.w %d0, (%a3)
220
221 add.l (%a0)+, %d2 /* go up to end address */
222 move.l %d2, (%a1)+
223
224 cmp.l %a1, %a2
225 bhi.s .g_tloop
226
227.g_no_tail:
228 movem.l (%sp), %d2-%d5/%a2-%a6 /* restore registers */
229 lea.l (9*4, %sp), %sp
142 rts 230 rts
231
143.gd_end: 232.gd_end:
144 .size lcd_grey_data,.gd_end-lcd_grey_data 233 .size lcd_grey_data,.gd_end-lcd_grey_data
diff --git a/firmware/target/coldfire/iaudio/m5/lcd-m5.c b/firmware/target/coldfire/iaudio/m5/lcd-m5.c
index 4f963795c7..be9d5a39b8 100644
--- a/firmware/target/coldfire/iaudio/m5/lcd-m5.c
+++ b/firmware/target/coldfire/iaudio/m5/lcd-m5.c
@@ -171,10 +171,13 @@ void lcd_blit(const unsigned char* data, int x, int by, int width,
171 } 171 }
172} 172}
173 173
174/* Helper function for lcd_grey_phase_blit(). */
175void lcd_grey_data(unsigned char *values, unsigned char *phases, int count);
176
174/* Performance function that works with an external buffer 177/* Performance function that works with an external buffer
175 note that by and bheight are in 4-pixel units! */ 178 note that by and bheight are in 4-pixel units! */
176void lcd_grey_phase_blit(const struct grey_data *data, int x, int by, 179void lcd_grey_phase_blit(unsigned char *values, unsigned char *phases,
177 int width, int bheight, int stride) 180 int x, int by, int width, int bheight, int stride)
178{ 181{
179 stride <<= 2; /* 4 pixels per block */ 182 stride <<= 2; /* 4 pixels per block */
180 while (bheight--) 183 while (bheight--)
@@ -182,8 +185,9 @@ void lcd_grey_phase_blit(const struct grey_data *data, int x, int by,
182 lcd_write_command_ex(LCD_CNTL_PAGE, by++, -1); 185 lcd_write_command_ex(LCD_CNTL_PAGE, by++, -1);
183 lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1); 186 lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1);
184 lcd_write_command(LCD_CNTL_DATA_WRITE); 187 lcd_write_command(LCD_CNTL_DATA_WRITE);
185 lcd_grey_data(data, width); 188 lcd_grey_data(values, phases, width);
186 data += stride; 189 values += stride;
190 phases += stride;
187 } 191 }
188} 192}
189 193
diff --git a/firmware/target/coldfire/iriver/h100/lcd-as-h100.S b/firmware/target/coldfire/iriver/h100/lcd-as-h100.S
index df410fa379..776e22a6c4 100644
--- a/firmware/target/coldfire/iriver/h100/lcd-as-h100.S
+++ b/firmware/target/coldfire/iriver/h100/lcd-as-h100.S
@@ -100,59 +100,148 @@ lcd_write_data:
100 .type lcd_grey_data,@function 100 .type lcd_grey_data,@function
101 101
102lcd_grey_data: 102lcd_grey_data:
103 lea.l (-4*4, %sp), %sp 103 lea.l (-9*4, %sp), %sp
104 movem.l %d2-%d5, (%sp) 104 movem.l %d2-%d5/%a2-%a6, (%sp) /* free some registers */
105 movem.l (4*4+4, %sp), %a0-%a1 /* Data pointer */ 105 movem.l (9*4+4, %sp), %a0-%a2 /* values, phases, length */
106 move.l %a1, %d0 /* Length */ 106 lea.l (%a1, %a2.l*4), %a2 /* end address */
107 moveq #8, %d1 107 moveq #8, %d1
108 or.l %d1, (MBAR2+0xb4) /* A0 = 1 (data) */ 108 or.l %d1, (MBAR2+0xb4) /* A0 = 1 (data) */
109 lea 0xf0000000, %a1 /* LCD data port */ 109 lea 0xf0000000, %a3 /* LCD data port */
110 move.l #0xff00ff00, %d2 /* mask for splitting value/phase pairs */ 110
111 111 moveq.l #15, %d3
112.greyloop: 112 add.l %a1, %d3
113 movem.l (%a0), %d4-%d5 /* fetch 4 pixel phase/value pairs at once */ 113 and.l #0xfffffff0, %d3 /* first line bound */
114 /* %d4 = p0v0p1v1, %d5 = p2v2p3v3 */ 114 move.l %a2, %d1
115 move.l %d2, %d3 /* copy mask */ 115 and.l #0xfffffff0, %d1 /* last line bound */
116 and.l %d4, %d3 /* %d3 = p0--p1-- */ 116 cmp.l %d3, %d1
117 eor.l %d3, %d4 /* %d4 = --v0--v1 */ 117 bls.w .g_tloop /* no lines to copy - jump to tail loop */
118 lsr.l #8, %d3 /* %d3 = --p0--p1 */ 118 cmp.l %a1, %d0
119 119 bls.s .g_lloop /* no head blocks - jump to line loop */
120 bclr.l #23, %d3 /* Z = !(p0 & 0x80); p0 &= ~0x80; */ 120
121 seq.b %d1 /* %d1 = ........................00000000 */ 121.g_hloop:
122 lsl.l #2, %d1 /* %d1 = ......................00000000.. */ 122 move.l (%a1), %d2 /* fetch 4 pixel phases */
123 bclr.l #7, %d3 /* Z = !(p1 & 0x80); p1 &= ~0x80; */ 123
124 seq.b %d1 /* %d1 = ......................0011111111 */ 124 bclr.l #31, %d2 /* Z = !(p0 & 0x80); p0 &= ~0x80; */
125 lsl.l #2, %d1 /* %d1 = ....................0011111111.. */ 125 seq.b %d0 /* %d0 = ........................00000000 */
126 lsl.l #2, %d0 /* %d0 = ......................00000000.. */
127 bclr.l #23, %d2 /* Z = !(p1 & 0x80); p1 &= ~0x80; */
128 seq.b %d0 /* %d0 = ......................0011111111 */
129 lsl.l #2, %d0 /* %d0 = ....................0011111111.. */
130 bclr.l #15, %d2 /* Z = !(p2 & 0x80); p2 &= ~0x80; */
131 seq.b %d0 /* %d0 = ....................001122222222 */
132 lsl.l #2, %d0 /* %d0 = ..................001122222222.. */
133 bclr.l #7, %d2 /* Z = !(p3 & 0x80); p3 &= ~0x80; */
134 seq.b %d0 /* %d0 = ..................00112233333333 */
135 lsr.l #6, %d0 /* %d0 = ........................00112233 */
136 move.w %d0, (%a3) /* write pixel block */
137
138 add.l (%a0)+, %d2 /* add 4 pixel values to the phases */
139 move.l %d2, (%a1)+ /* store new phases, advance pointer */
140
141 cmp.l %a1, %d3 /* go up to first line bound */
142 bhi.s .g_hloop
143
144.g_lloop:
145 movem.l (%a1), %d2-%d5
126 146
127 add.l %d4, %d3 /* p0 += v0; p1 += v1; */ 147 bclr.l #31, %d2
128 move.b %d3, (2, %a0) /* store p1 */ 148 seq.b %d0
129 swap %d3 149 lsl.l #2, %d0
130 move.b %d3, (%a0) /* store p0 */ 150 bclr.l #23, %d2
131 151 seq.b %d0
132 move.l %d2, %d3 /* copy mask */ 152 lsl.l #2, %d0
133 and.l %d5, %d3 /* %d3 = p2--p3-- */ 153 bclr.l #15, %d2
134 eor.l %d3, %d5 /* %d5 = --v2--v3 */ 154 seq.b %d0
135 lsr.l #8, %d3 /* %d3 = --p2--p3 */ 155 lsl.l #2, %d0
136 156 bclr.l #7, %d2
137 bclr.l #23, %d3 /* Z = !(p2 & 0x80); p2 &= ~0x80; */ 157 seq.b %d0
138 seq.b %d1 /* %d1 = ....................001122222222 */ 158 lsr.l #6, %d0
139 lsl.l #2, %d1 /* %d1 = ..................001122222222.. */ 159 move.w %d0, (%a3)
140 bclr.l #7, %d3 /* Z = !(p3 & 0x80); p3 &= ~0x80; */ 160
141 seq.b %d1 /* %d1 = ..................00112233333333 */ 161 bclr.l #31, %d3
142 lsr.l #6, %d1 /* %d1 = ........................00112233 */ 162 seq.b %d0
143 163 lsl.l #2, %d0
144 add.l %d5, %d3 /* p2 += v2; p3 += v3; */ 164 bclr.l #23, %d3
145 move.b %d3, (6, %a0) /* store p3 */ 165 seq.b %d0
146 swap %d3 166 lsl.l #2, %d0
147 move.b %d3, (4, %a0) /* store p2 */ 167 bclr.l #15, %d3
148 168 seq.b %d0
149 move.w %d1, (%a1) /* write pixel block */ 169 lsl.l #2, %d0
150 addq.l #8, %a0 /* advance address pointer */ 170 bclr.l #7, %d3
151 subq.l #1, %d0 /* any blocks left? */ 171 seq.b %d0
152 bne.b .greyloop 172 lsr.l #6, %d0
153 173 move.w %d0, (%a3)
154 movem.l (%sp), %d2-%d5 174
155 lea.l (4*4, %sp), %sp 175 bclr.l #31, %d4
176 seq.b %d0
177 lsl.l #2, %d0
178 bclr.l #23, %d4
179 seq.b %d0
180 lsl.l #2, %d0
181 bclr.l #15, %d4
182 seq.b %d0
183 lsl.l #2, %d0
184 bclr.l #7, %d4
185 seq.b %d0
186 lsr.l #6, %d0
187 move.w %d0, (%a3)
188
189 bclr.l #31, %d5
190 seq.b %d0
191 lsl.l #2, %d0
192 bclr.l #23, %d5
193 seq.b %d0
194 lsl.l #2, %d0
195 bclr.l #15, %d5
196 seq.b %d0
197 lsl.l #2, %d0
198 bclr.l #7, %d5
199 seq.b %d0
200 lsr.l #6, %d0
201 move.w %d0, (%a3)
202
203 movem.l (%a0), %d0/%a4-%a6
204 lea.l (16, %a0), %a0
205 add.l %d0, %d2
206 add.l %a4, %d3
207 add.l %a5, %d4
208 add.l %a6, %d5
209 movem.l %d2-%d5, (%a1)
210 lea.l (16, %a1), %a1
211
212 cmp.l %a1, %d1 /* go up to last line bound */
213 bhi.w .g_lloop
214
215 cmp.l %a1, %a2
216 bls.s .g_no_tail
217
218.g_tloop:
219 move.l (%a1), %d2
220
221 bclr.l #31, %d2
222 seq.b %d0
223 lsl.l #2, %d0
224 bclr.l #23, %d2
225 seq.b %d0
226 lsl.l #2, %d0
227 bclr.l #15, %d2
228 seq.b %d0
229 lsl.l #2, %d0
230 bclr.l #7, %d2
231 seq.b %d0
232 lsr.l #6, %d0
233 move.w %d0, (%a3)
234
235 add.l (%a0)+, %d2
236 move.l %d2, (%a1)+
237
238 cmp.l %a1, %a2 /* go up to end address */
239 bhi.s .g_tloop
240
241.g_no_tail:
242 movem.l (%sp), %d2-%d5/%a2-%a6 /* restore registers */
243 lea.l (9*4, %sp), %sp
156 rts 244 rts
245
157.gd_end: 246.gd_end:
158 .size lcd_grey_data,.gd_end-lcd_grey_data 247 .size lcd_grey_data,.gd_end-lcd_grey_data
diff --git a/firmware/target/coldfire/iriver/h100/lcd-h100.c b/firmware/target/coldfire/iriver/h100/lcd-h100.c
index c17de952c3..2ba19255da 100644
--- a/firmware/target/coldfire/iriver/h100/lcd-h100.c
+++ b/firmware/target/coldfire/iriver/h100/lcd-h100.c
@@ -180,10 +180,13 @@ void lcd_blit(const unsigned char* data, int x, int by, int width,
180 } 180 }
181} 181}
182 182
183/* Helper function for lcd_grey_phase_blit(). */
184void lcd_grey_data(unsigned char *values, unsigned char *phases, int count);
185
183/* Performance function that works with an external buffer 186/* Performance function that works with an external buffer
184 note that by and bheight are in 4-pixel units! */ 187 note that by and bheight are in 4-pixel units! */
185void lcd_grey_phase_blit(const struct grey_data *data, int x, int by, 188void lcd_grey_phase_blit(unsigned char *values, unsigned char *phases,
186 int width, int bheight, int stride) 189 int x, int by, int width, int bheight, int stride)
187{ 190{
188 stride <<= 2; /* 4 pixels per block */ 191 stride <<= 2; /* 4 pixels per block */
189 while (bheight--) 192 while (bheight--)
@@ -191,8 +194,9 @@ void lcd_grey_phase_blit(const struct grey_data *data, int x, int by,
191 lcd_write_command_ex(LCD_CNTL_PAGE, by++, -1); 194 lcd_write_command_ex(LCD_CNTL_PAGE, by++, -1);
192 lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1); 195 lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1);
193 lcd_write_command(LCD_CNTL_DATA_WRITE); 196 lcd_write_command(LCD_CNTL_DATA_WRITE);
194 lcd_grey_data(data, width); 197 lcd_grey_data(values, phases, width);
195 data += stride; 198 values += stride;
199 phases += stride;
196 } 200 }
197} 201}
198 202