summaryrefslogtreecommitdiff
path: root/firmware/target/sh/archos
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2008-01-04 23:42:38 +0000
committerJens Arnold <amiconn@rockbox.org>2008-01-04 23:42:38 +0000
commitfeb5b15e9bf9292e3d4d82ea1e01ab3557fb1240 (patch)
treed854c9a6fbbb3263537071fb02df349fdfa62361 /firmware/target/sh/archos
parentd3586837fa9221a7ef104550b4c0aadc1a6ea77c (diff)
downloadrockbox-feb5b15e9bf9292e3d4d82ea1e01ab3557fb1240.tar.gz
rockbox-feb5b15e9bf9292e3d4d82ea1e01ab3557fb1240.zip
All-new greyscale library, replacing the old one. Features: (1) Drawing/updating is faster than the old grayscale lib at full depth. (2) Always 129 shades instead of 2..33 shades. (3) No graininess caused by frequent updates (mpegplayer, doom, ...). (4) Needs less memory than the old grayscale lib at full depth. * The tradeoff is slightly higher CPU load in the ISR (frames are calculated 'live') and an extra function in the core. * Ported all plugins which used the graylib to use the new one. * Some slight optimisations for archos and H1x0 LCD update.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15998 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/sh/archos')
-rw-r--r--firmware/target/sh/archos/lcd-archos-bitmap.c19
-rw-r--r--firmware/target/sh/archos/lcd-as-archos-bitmap.S259
2 files changed, 220 insertions, 58 deletions
diff --git a/firmware/target/sh/archos/lcd-archos-bitmap.c b/firmware/target/sh/archos/lcd-archos-bitmap.c
index 28600a9769..17c4d76092 100644
--- a/firmware/target/sh/archos/lcd-archos-bitmap.c
+++ b/firmware/target/sh/archos/lcd-archos-bitmap.c
@@ -155,10 +155,26 @@ void lcd_blit(const unsigned char* data, int x, int by, int width,
155 } 155 }
156} 156}
157 157
158/* Performance function that works with an external buffer
159 note that by and bheight are in 8-pixel units! */
160void lcd_grey_phase_blit(const struct grey_data *data, int x, int by,
161 int width, int bheight, int stride)
162{
163 stride <<= 3; /* 8 pixels per block */
164 while (bheight--)
165 {
166 lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf));
167 lcd_write_command (LCD_CNTL_HIGHCOL | (((x+xoffset)>>4) & 0xf));
168 lcd_write_command (LCD_CNTL_LOWCOL | ((x+xoffset) & 0xf));
169
170 lcd_grey_data(data, width);
171 data += stride;
172 }
173}
174
158 175
159/* Update the display. 176/* Update the display.
160 This must be called after all other LCD functions that change the display. */ 177 This must be called after all other LCD functions that change the display. */
161void lcd_update(void) ICODE_ATTR;
162void lcd_update(void) 178void lcd_update(void)
163{ 179{
164 int y; 180 int y;
@@ -175,7 +191,6 @@ void lcd_update(void)
175} 191}
176 192
177/* Update a fraction of the display. */ 193/* Update a fraction of the display. */
178void lcd_update_rect(int, int, int, int) ICODE_ATTR;
179void lcd_update_rect(int x, int y, int width, int height) 194void lcd_update_rect(int x, int y, int width, int height)
180{ 195{
181 int ymax; 196 int ymax;
diff --git a/firmware/target/sh/archos/lcd-as-archos-bitmap.S b/firmware/target/sh/archos/lcd-as-archos-bitmap.S
index bef231c3c7..a84ce50686 100644
--- a/firmware/target/sh/archos/lcd-as-archos-bitmap.S
+++ b/firmware/target/sh/archos/lcd-as-archos-bitmap.S
@@ -81,26 +81,25 @@
81 */ 81 */
82 82
83_lcd_write_command: 83_lcd_write_command:
84 mov.l .lcdr,r3 /* put lcd data port address in r3 */ 84 mov.l .lcdr, r3 /* put lcd data port address in r3 */
85 mov r4,r1 /* copy data byte to r1 */ 85 mov r4, r1 /* copy data byte to r1 */
86 mov #1,r5 /* set byte count to 1 (!) */
87 86
88 /* This code will fail if an interrupt changes the contents of PBDRL. 87 /* This code will fail if an interrupt changes the contents of PBDRL.
89 * If so, we must disable the interrupt here. */ 88 * If so, we must disable the interrupt here. */
90 89
91 mov.b @r3,r0 /* r0 = PBDRL */ 90 mov.b @r3, r0 /* r0 = PBDRL */
92 or #(LCD_SD),r0 /* r0 |= LCD_SD */ 91 mov r4, r5 /* (fake) end address = current address */
93 and #(~(LCD_CS|LCD_DS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */ 92 or #(LCD_SD), r0 /* r0 |= LCD_SD */
93 and #(~(LCD_CS|LCD_DS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */
94 94
95 bra .single_transfer /* jump into the transfer loop */ 95 bra .single_transfer /* jump into the transfer loop */
96 neg r0,r2 /* r2 = 0 - r0 */ 96 neg r0, r2 /* r2 = 0 - r0 */
97 97
98 98
99 .align 2 99 .align 2
100 .global _lcd_write_data 100 .global _lcd_write_data
101 .type _lcd_write_data,@function 101 .type _lcd_write_data,@function
102 102
103
104/* A high performance function to write data to the display, 103/* A high performance function to write data to the display,
105 * one or multiple bytes. 104 * one or multiple bytes.
106 * 105 *
@@ -117,8 +116,8 @@ _lcd_write_command:
117 */ 116 */
118 117
119_lcd_write_data: 118_lcd_write_data:
120 mov.l .lcdr,r3 /* put lcd data port address in r3 */ 119 mov.l .lcdr, r3 /* put lcd data port address in r3 */
121 nop /* align here */ 120 add r4, r5 /* end address */
122 121
123 /* This code will fail if an interrupt changes the contents of PBDRL. 122 /* This code will fail if an interrupt changes the contents of PBDRL.
124 * If so, we must disable the interrupt here. If disabling interrupts 123 * If so, we must disable the interrupt here. If disabling interrupts
@@ -127,85 +126,233 @@ _lcd_write_data:
127 * disable/precalculate/transfer/enable for each iteration. However, 126 * disable/precalculate/transfer/enable for each iteration. However,
128 * this would significantly decrease performance. */ 127 * this would significantly decrease performance. */
129 128
130 mov.b @r3,r0 /* r0 = PBDRL */ 129 mov.b @r3, r0 /* r0 = PBDRL */
131 or #(LCD_DS|LCD_SD),r0 /* r0 |= LCD_DS|LCD_SD */ 130 or #(LCD_DS|LCD_SD), r0 /* r0 |= LCD_DS|LCD_SD */
132 and #(~(LCD_CS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_SC) */ 131 and #(~(LCD_CS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_SC) */
133 neg r0,r2 /* r2 = 0 - r0 */ 132 neg r0, r2 /* r2 = 0 - r0 */
134 133
135 /* loop exploits that SD is on bit 0 for recorders and Ondios */ 134 /* loop exploits that SD is on bit 0 for recorders and Ondios */
136 135
137 .align 2 136 .align 2
138.multi_transfer: 137.multi_transfer:
139 mov.b @r4+,r1 /* load data byte from memory */ 138 mov.b @r4+, r1 /* load data byte from memory */
140 nop 139 nop
141 140
142.single_transfer: 141.single_transfer:
143 shll16 r1 /* shift data to most significant byte */ 142 shll16 r1 /* shift data to most significant byte */
144 shll8 r1 143 shll8 r1
145 not r1,r1 /* and invert for use with negc */ 144 not r1, r1 /* and invert for use with negc */
146 145
147 shll r1 /* shift the MSB into carry */ 146 shll r1 /* shift the MSB into carry */
148 negc r2,r0 /* carry to SD, SC low */ 147 negc r2, r0 /* carry to SD, SC low */
149 shll r1 /* next shift here for alignment */ 148 shll r1 /* next shift here for alignment */
150 mov.b r0,@r3 /* set data to port */ 149 mov.b r0, @r3 /* set data to port */
151 or #(LCD_SC),r0 /* rise SC (independent of SD level) */ 150 or #(LCD_SC), r0 /* rise SC (independent of SD level) */
152 mov.b r0,@r3 /* set to port */ 151 mov.b r0, @r3 /* set to port */
153 152
154 negc r2,r0 153 negc r2, r0
155 mov.b r0,@r3 154 mov.b r0, @r3
156 or #(LCD_SC),r0 155 or #(LCD_SC), r0
157 mov.b r0,@r3 156 mov.b r0, @r3
158 157
159 shll r1 158 shll r1
160 negc r2,r0 159 negc r2, r0
161 shll r1 160 shll r1
162 mov.b r0,@r3 161 mov.b r0, @r3
163 or #(LCD_SC),r0 162 or #(LCD_SC), r0
164 mov.b r0,@r3 163 mov.b r0, @r3
165 164
166 negc r2,r0 165 negc r2, r0
167 mov.b r0,@r3 166 mov.b r0, @r3
168 or #(LCD_SC),r0 167 or #(LCD_SC), r0
169 mov.b r0,@r3 168 mov.b r0, @r3
170 169
171 shll r1 170 shll r1
172 negc r2,r0 171 negc r2, r0
173 shll r1 172 shll r1
174 mov.b r0,@r3 173 mov.b r0, @r3
175 or #(LCD_SC),r0 174 or #(LCD_SC), r0
176 mov.b r0,@r3 175 mov.b r0, @r3
177 176
178 negc r2,r0 177 negc r2, r0
179 mov.b r0,@r3 178 mov.b r0, @r3
180 or #(LCD_SC),r0 179 or #(LCD_SC), r0
181 mov.b r0,@r3 180 mov.b r0, @r3
182 181
183 shll r1 182 shll r1
184 negc r2,r0 183 negc r2, r0
185 shll r1 184 shll r1
186 mov.b r0,@r3 185 mov.b r0, @r3
187 or #(LCD_SC),r0 186 or #(LCD_SC), r0
188 mov.b r0,@r3 187 mov.b r0, @r3
188
189 negc r2, r0
190 mov.b r0, @r3
191 or #(LCD_SC), r0
192 mov.b r0, @r3
193
194 cmp/hi r4, r5 /* some blocks left? */
195 bt .multi_transfer
196
197 or #(LCD_CS|LCD_DS|LCD_SD|LCD_SC), r0 /* restore port */
198 rts
199 mov.b r0, @r3
200
201 /* This is the place to reenable the interrupts, if we have disabled
202 * them. See above. */
203
204
205 .align 2
206 .global _lcd_grey_data
207 .type _lcd_grey_data,@function
208
209/* A high performance function to write grey phase data to the display,
210 * one or multiple pixels.
211 *
212 * Arguments:
213 * r4 - data address, (phase,value)-pairs
214 * r5 - pixel block count
215 *
216 * Register usage:
217 * r0 - current pixel value
218 * r1 - scratch
219 * r2 - precalculated port value (CS and SC low, DS and SD high),
220 * negated (neg)!
221 * r3 - lcd port address
222 * r5 - end address
223 * r6/r7 - current/next pixel phase
224 * r8 - current block address (for writing back phase)
225 * r9 - 0x80 (for phase modification)
226 */
227
228_lcd_grey_data:
229 mov.l r8, @-r15 /* save r8 */
230 shll2 r5 /* v */
231 mov.l r9, @-r15 /* save r9 */
232 shll2 r5 /* r5 *= 16; (8 pixel per block * 2 bytes/pixel) */
233 mov.l .lcdr, r3 /* put lcd data port address in r3 */
234 add r4, r5 /* end address */
189 235
190 negc r2,r0 236 /* This code will fail if an interrupt changes the contents of PBDRL.
191 mov.b r0,@r3 237 * If so, we must disable the interrupt here. If disabling interrupts
192 or #(LCD_SC),r0 238 * for a long time is undesirable, the loop has to be rewritten to
193 mov.b r0,@r3 239 * disable/precalculate/transfer/enable for each iteration. However,
240 * this would significantly decrease performance. */
194 241
195 add #-1,r5 /* decrease byte count */ 242 mov.b @r3, r0 /* r0 = PBDRL */
196 tst r5,r5 /* r5 == 0 ? */ 243 mov r4, r8 /* copy start address */
197 bf .multi_transfer /* no: next iteration */ 244 mov.b @r4+, r6 /* fetch first pixel phase */
245 or #(LCD_DS|LCD_SD), r0 /* r0 |= LCD_DS|LCD_SD */
246 and #(~(LCD_CS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_SC) */
247 neg r0, r2 /* r2 = 0 - r0 */
248 mov #0x80, r9 /* for phase modification - "or #imm,xx" only allows r0 */
249
250 /* loop exploits that SD is on bit 0 for recorders and Ondios */
198 251
199 or #(LCD_CS|LCD_DS|LCD_SD|LCD_SC),r0 /* restore port */ 252.greyloop:
253 cmp/pz r6 /* phase non-negative? */
254 mov.b @r4+, r0 /* fetch pixel value */
255 negc r2, r1 /* T -> SD, SC low */
256 mov.b r1, @r3 /* set port */
257 or r9, r6 /* r6 -= (r6 >= 0) ? 128 : 0; */
258 mov.b @r4+, r7 /* fetch next pixel phase */
259 add #(LCD_SC), r1 /* rise SC */
260 mov.b r1, @r3 /* set port */
261 add r6, r0 /* calculate new phase */
262 mov.b r0, @r8 /* store phase */
263
264 cmp/pz r7
265 mov.b @r4+, r0
266 negc r2, r1
267 mov.b r1, @r3
268 or r9, r7
269 mov.b @r4+, r6
270 add #(LCD_SC), r1
271 mov.b r1, @r3
272 add r7, r0
273 mov.b r0, @(2,r8)
274
275 cmp/pz r6
276 mov.b @r4+, r0
277 negc r2, r1
278 mov.b r1, @r3
279 or r9, r6
280 mov.b @r4+, r7
281 add #(LCD_SC), r1
282 mov.b r1, @r3
283 add r6, r0
284 mov.b r0, @(4,r8)
285
286 cmp/pz r7
287 mov.b @r4+, r0
288 negc r2, r1
289 mov.b r1, @r3
290 or r9, r7
291 mov.b @r4+, r6
292 add #(LCD_SC), r1
293 mov.b r1, @r3
294 add r7, r0
295 mov.b r0, @(6,r8)
296
297 cmp/pz r6
298 mov.b @r4+, r0
299 negc r2, r1
300 mov.b r1, @r3
301 or r9, r6
302 mov.b @r4+, r7
303 add #(LCD_SC), r1
304 mov.b r1, @r3
305 add r6, r0
306 mov.b r0, @(8,r8)
307
308 cmp/pz r7
309 mov.b @r4+, r0
310 negc r2, r1
311 mov.b r1, @r3
312 or r9, r7
313 mov.b @r4+, r6
314 add #(LCD_SC), r1
315 mov.b r1, @r3
316 add r7, r0
317 mov.b r0, @(10,r8)
318
319 cmp/pz r6
320 mov.b @r4+, r0
321 negc r2, r1
322 mov.b r1, @r3
323 or r9, r6
324 mov.b @r4+, r7
325 add #(LCD_SC), r1
326 mov.b r1, @r3
327 add r6, r0
328 mov.b r0, @(12,r8)
329
330 cmp/pz r7
331 mov.b @r4+, r0
332 negc r2, r1
333 mov.b r1, @r3
334 or r9, r7
335 mov.b @r4+, r6
336 add #(LCD_SC), r1
337 mov.b r1, @r3
338 add r7, r0
339 mov.b r0, @(14,r8)
340
341 add #16, r8 /* advance current block address */
342 cmp/hi r4, r5 /* some blocks left? */
343 bt .greyloop
344
345 mov.l @r15+, r9 /* restore r9 */
346 mov #(LCD_CS|LCD_DS|LCD_SD|LCD_SC), r0
347 mov.l @r15+, r8 /* restore r8 */
348 or r0, r1 /* restore port */
200 rts 349 rts
201 mov.b r0,@r3 350 mov.b r1, @r3
202 351
203 /* This is the place to reenable the interrupts, if we have disabled 352 /* This is the place to reenable the interrupts, if we have disabled
204 * them. See above. */ 353 * them. See above. */
205 354
355
206 .align 2 356 .align 2
207.lcdr: 357.lcdr:
208 .long LCDR 358 .long LCDR
209
210.end:
211 .size _lcd_write_command,.end-_lcd_write_command