diff options
Diffstat (limited to 'firmware/drivers/lcd.S')
-rwxr-xr-x | firmware/drivers/lcd.S | 238 |
1 files changed, 86 insertions, 152 deletions
diff --git a/firmware/drivers/lcd.S b/firmware/drivers/lcd.S index d9e7092c94..ed0bc8d15b 100755 --- a/firmware/drivers/lcd.S +++ b/firmware/drivers/lcd.S | |||
@@ -48,23 +48,23 @@ | |||
48 | * - DS -> Data Selection line, latched at the rising edge | 48 | * - DS -> Data Selection line, latched at the rising edge |
49 | * of the 8th serial clock (*) : | 49 | * of the 8th serial clock (*) : |
50 | * 0 : instruction register, | 50 | * 0 : instruction register, |
51 | * 1 : data register; | 51 | * 1 : data register; |
52 | * - SC -> Serial Clock line (SDA). | 52 | * - SC -> Serial Clock line (SDA). |
53 | * - SD -> Serial Data line (SCK), latched at the rising edge | 53 | * - SD -> Serial Data line (SCK), latched at the rising edge |
54 | * of each serial clock (*). | 54 | * of each serial clock (*). |
55 | * | 55 | * |
56 | * _ _ | 56 | * _ _ |
57 | * /CS \ / | 57 | * /CS \ / |
58 | * \______________________________________________________/ | 58 | * \______________________________________________________/ |
59 | * _____ ____ ____ ____ ____ ____ ____ ____ ____ _____ | 59 | * _____ ____ ____ ____ ____ ____ ____ ____ ____ _____ |
60 | * SD \/ D7 \/ D6 \/ D5 \/ D4 \/ D3 \/ D2 \/ D1 \/ D0 \/ | 60 | * SD \/ D7 \/ D6 \/ D5 \/ D4 \/ D3 \/ D2 \/ D1 \/ D0 \/ |
61 | * _____/\____/\____/\____/\____/\____/\____/\____/\____/\_____ | 61 | * _____/\____/\____/\____/\____/\____/\____/\____/\____/\_____ |
62 | * | 62 | * |
63 | * _____ _ _ _ _ _ _ _ ________ | 63 | * _____ _ _ _ _ _ _ _ ________ |
64 | * SC \ * \ * \ * \ * \ * \ * \ * \ * | 64 | * SC \ * \ * \ * \ * \ * \ * \ * \ * |
65 | * \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ | 65 | * \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ |
66 | * _ _________________________________________________________ | 66 | * _ _________________________________________________________ |
67 | * DS \/ | 67 | * DS \/ |
68 | * _/\_________________________________________________________ | 68 | * _/\_________________________________________________________ |
69 | * | 69 | * |
70 | */ | 70 | */ |
@@ -93,14 +93,14 @@ _lcd_write_command: | |||
93 | mov.l .lcdr,r3 /* put lcd data port address in r3 */ | 93 | mov.l .lcdr,r3 /* put lcd data port address in r3 */ |
94 | mov r4,r1 /* copy data byte to r1 */ | 94 | mov r4,r1 /* copy data byte to r1 */ |
95 | mov #1,r5 /* set byte count to 1 (!) */ | 95 | mov #1,r5 /* set byte count to 1 (!) */ |
96 | 96 | ||
97 | /* This code will fail if an interrupt changes the contents of PBDRL. | 97 | /* This code will fail if an interrupt changes the contents of PBDRL. |
98 | * If so, we must disable the interrupt here. */ | 98 | * If so, we must disable the interrupt here. */ |
99 | 99 | ||
100 | mov.b @r3,r0 /* r0 = PBDRL */ | 100 | mov.b @r3,r0 /* r0 = PBDRL */ |
101 | or #(LCD_SD),r0 /* r0 |= LCD_SD */ | 101 | or #(LCD_SD),r0 /* r0 |= LCD_SD */ |
102 | and #(~(LCD_CS|LCD_DS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */ | 102 | and #(~(LCD_CS|LCD_DS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */ |
103 | 103 | ||
104 | bra .single_transfer /* jump into the transfer loop */ | 104 | bra .single_transfer /* jump into the transfer loop */ |
105 | neg r0,r2 /* r2 = 0 - r0 */ | 105 | neg r0,r2 /* r2 = 0 - r0 */ |
106 | 106 | ||
@@ -131,7 +131,7 @@ _lcd_write_data: | |||
131 | 131 | ||
132 | /* This code will fail if an interrupt changes the contents of PBDRL. | 132 | /* This code will fail if an interrupt changes the contents of PBDRL. |
133 | * If so, we must disable the interrupt here. If disabling interrupts | 133 | * If so, we must disable the interrupt here. If disabling interrupts |
134 | * for a long time (~9200 clks = ~830 µs for transferring 112 bytes on | 134 | * for a long time (~9200 clks = ~830 µs for transferring 112 bytes on |
135 | * recorders)is undesirable, the loop has to be rewritten to | 135 | * recorders)is undesirable, the loop has to be rewritten to |
136 | * disable/precalculate/transfer/enable for each iteration. However, | 136 | * disable/precalculate/transfer/enable for each iteration. However, |
137 | * this would significantly decrease performance. */ | 137 | * this would significantly decrease performance. */ |
@@ -148,7 +148,7 @@ _lcd_write_data: | |||
148 | .multi_transfer: | 148 | .multi_transfer: |
149 | mov.b @r4+,r1 /* load data byte from memory */ | 149 | mov.b @r4+,r1 /* load data byte from memory */ |
150 | 150 | ||
151 | .single_transfer: | 151 | .single_transfer: |
152 | shll16 r1 /* shift data to most significant byte */ | 152 | shll16 r1 /* shift data to most significant byte */ |
153 | shll8 r1 | 153 | shll8 r1 |
154 | 154 | ||
@@ -157,85 +157,85 @@ _lcd_write_data: | |||
157 | /* uses neg here for compatibility with recorder version */ | 157 | /* uses neg here for compatibility with recorder version */ |
158 | bt 1f /* data bit = 1? */ | 158 | bt 1f /* data bit = 1? */ |
159 | and #(~LCD_SD),r0 /* no: r0 &= ~LCD_SD */ | 159 | and #(~LCD_SD),r0 /* no: r0 &= ~LCD_SD */ |
160 | 1: | 160 | 1: |
161 | shll r1 /* next shift here for alignment */ | 161 | shll r1 /* next shift here for alignment */ |
162 | mov.b r0,@r3 /* set data to port */ | 162 | mov.b r0,@r3 /* set data to port */ |
163 | or #(LCD_SC),r0 /* rise SC (independent of SD level) */ | 163 | or #(LCD_SC),r0 /* rise SC (independent of SD level) */ |
164 | mov.b r0,@r3 /* set to port */ | 164 | mov.b r0,@r3 /* set to port */ |
165 | 165 | ||
166 | neg r2,r0 | 166 | neg r2,r0 |
167 | bt 1f | 167 | bt 1f |
168 | and #(~LCD_SD),r0 | 168 | and #(~LCD_SD),r0 |
169 | 1: | 169 | 1: |
170 | mov.b r0,@r3 | 170 | mov.b r0,@r3 |
171 | or #(LCD_SC),r0 | 171 | or #(LCD_SC),r0 |
172 | mov.b r0,@r3 | 172 | mov.b r0,@r3 |
173 | 173 | ||
174 | shll r1 | 174 | shll r1 |
175 | neg r2,r0 | 175 | neg r2,r0 |
176 | bt 1f | 176 | bt 1f |
177 | and #(~LCD_SD),r0 | 177 | and #(~LCD_SD),r0 |
178 | 1: | 178 | 1: |
179 | shll r1 | 179 | shll r1 |
180 | mov.b r0,@r3 | 180 | mov.b r0,@r3 |
181 | or #(LCD_SC),r0 | 181 | or #(LCD_SC),r0 |
182 | mov.b r0,@r3 | 182 | mov.b r0,@r3 |
183 | 183 | ||
184 | neg r2,r0 | 184 | neg r2,r0 |
185 | bt 1f | 185 | bt 1f |
186 | and #(~LCD_SD),r0 | 186 | and #(~LCD_SD),r0 |
187 | 1: | 187 | 1: |
188 | mov.b r0,@r3 | 188 | mov.b r0,@r3 |
189 | or #(LCD_SC),r0 | 189 | or #(LCD_SC),r0 |
190 | mov.b r0,@r3 | 190 | mov.b r0,@r3 |
191 | 191 | ||
192 | shll r1 | 192 | shll r1 |
193 | neg r2,r0 | 193 | neg r2,r0 |
194 | bt 1f | 194 | bt 1f |
195 | and #(~LCD_SD),r0 | 195 | and #(~LCD_SD),r0 |
196 | 1: | 196 | 1: |
197 | shll r1 | 197 | shll r1 |
198 | mov.b r0,@r3 | 198 | mov.b r0,@r3 |
199 | or #(LCD_SC),r0 | 199 | or #(LCD_SC),r0 |
200 | mov.b r0,@r3 | 200 | mov.b r0,@r3 |
201 | 201 | ||
202 | neg r2,r0 | 202 | neg r2,r0 |
203 | bt 1f | 203 | bt 1f |
204 | and #(~LCD_SD),r0 | 204 | and #(~LCD_SD),r0 |
205 | 1: | 205 | 1: |
206 | mov.b r0,@r3 | 206 | mov.b r0,@r3 |
207 | or #(LCD_SC),r0 | 207 | or #(LCD_SC),r0 |
208 | mov.b r0,@r3 | 208 | mov.b r0,@r3 |
209 | 209 | ||
210 | shll r1 | 210 | shll r1 |
211 | neg r2,r0 | 211 | neg r2,r0 |
212 | bt 1f | 212 | bt 1f |
213 | and #(~LCD_SD),r0 | 213 | and #(~LCD_SD),r0 |
214 | 1: | 214 | 1: |
215 | shll r1 | 215 | shll r1 |
216 | mov.b r0,@r3 | 216 | mov.b r0,@r3 |
217 | or #(LCD_SC),r0 | 217 | or #(LCD_SC),r0 |
218 | mov.b r0,@r3 | 218 | mov.b r0,@r3 |
219 | 219 | ||
220 | neg r2,r0 | 220 | neg r2,r0 |
221 | bt 1f | 221 | bt 1f |
222 | and #(~LCD_SD),r0 | 222 | and #(~LCD_SD),r0 |
223 | 1: | 223 | 1: |
224 | mov.b r0,@r3 | 224 | mov.b r0,@r3 |
225 | or #(LCD_SC),r0 | 225 | or #(LCD_SC),r0 |
226 | mov.b r0,@r3 | 226 | mov.b r0,@r3 |
227 | 227 | ||
228 | #else /* HAVE_LCD_CHARCELLS */ | 228 | #else /* HAVE_LCD_CHARCELLS */ |
229 | /* further optimized version, exploits that SD is on bit 0 for recorders */ | 229 | /* further optimized version, exploits that SD is on bit 0 for recorders */ |
230 | 230 | ||
231 | .align 2 | 231 | .align 2 |
232 | .multi_transfer: | 232 | .multi_transfer: |
233 | mov.b @r4+,r1 /* load data byte from memory */ | 233 | mov.b @r4+,r1 /* load data byte from memory */ |
234 | nop | 234 | nop |
235 | 235 | ||
236 | .single_transfer: | 236 | .single_transfer: |
237 | shll16 r1 /* shift data to most significant byte */ | 237 | shll16 r1 /* shift data to most significant byte */ |
238 | shll8 r1 | 238 | shll8 r1 |
239 | not r1,r1 /* and invert for use with negc */ | 239 | not r1,r1 /* and invert for use with negc */ |
240 | 240 | ||
241 | shll r1 /* shift the MSB into carry */ | 241 | shll r1 /* shift the MSB into carry */ |
@@ -245,46 +245,46 @@ _lcd_write_data: | |||
245 | or #(LCD_SC),r0 /* rise SC (independent of SD level) */ | 245 | or #(LCD_SC),r0 /* rise SC (independent of SD level) */ |
246 | mov.b r0,@r3 /* set to port */ | 246 | mov.b r0,@r3 /* set to port */ |
247 | 247 | ||
248 | negc r2,r0 | 248 | negc r2,r0 |
249 | mov.b r0,@r3 | 249 | mov.b r0,@r3 |
250 | or #(LCD_SC),r0 | 250 | or #(LCD_SC),r0 |
251 | mov.b r0,@r3 | 251 | mov.b r0,@r3 |
252 | 252 | ||
253 | shll r1 | 253 | shll r1 |
254 | negc r2,r0 | 254 | negc r2,r0 |
255 | shll r1 | 255 | shll r1 |
256 | mov.b r0,@r3 | 256 | mov.b r0,@r3 |
257 | or #(LCD_SC),r0 | 257 | or #(LCD_SC),r0 |
258 | mov.b r0,@r3 | 258 | mov.b r0,@r3 |
259 | 259 | ||
260 | negc r2,r0 | 260 | negc r2,r0 |
261 | mov.b r0,@r3 | 261 | mov.b r0,@r3 |
262 | or #(LCD_SC),r0 | 262 | or #(LCD_SC),r0 |
263 | mov.b r0,@r3 | 263 | mov.b r0,@r3 |
264 | 264 | ||
265 | shll r1 | 265 | shll r1 |
266 | negc r2,r0 | 266 | negc r2,r0 |
267 | shll r1 | 267 | shll r1 |
268 | mov.b r0,@r3 | 268 | mov.b r0,@r3 |
269 | or #(LCD_SC),r0 | 269 | or #(LCD_SC),r0 |
270 | mov.b r0,@r3 | 270 | mov.b r0,@r3 |
271 | 271 | ||
272 | negc r2,r0 | 272 | negc r2,r0 |
273 | mov.b r0,@r3 | 273 | mov.b r0,@r3 |
274 | or #(LCD_SC),r0 | 274 | or #(LCD_SC),r0 |
275 | mov.b r0,@r3 | 275 | mov.b r0,@r3 |
276 | 276 | ||
277 | shll r1 | 277 | shll r1 |
278 | negc r2,r0 | 278 | negc r2,r0 |
279 | shll r1 | 279 | shll r1 |
280 | mov.b r0,@r3 | 280 | mov.b r0,@r3 |
281 | or #(LCD_SC),r0 | 281 | or #(LCD_SC),r0 |
282 | mov.b r0,@r3 | 282 | mov.b r0,@r3 |
283 | 283 | ||
284 | negc r2,r0 | 284 | negc r2,r0 |
285 | mov.b r0,@r3 | 285 | mov.b r0,@r3 |
286 | or #(LCD_SC),r0 | 286 | or #(LCD_SC),r0 |
287 | mov.b r0,@r3 | 287 | mov.b r0,@r3 |
288 | 288 | ||
289 | #endif /* HAVE_LCD_CHARCELLS */ | 289 | #endif /* HAVE_LCD_CHARCELLS */ |
290 | 290 | ||
@@ -293,7 +293,7 @@ _lcd_write_data: | |||
293 | bf .multi_transfer /* no: next iteration */ | 293 | bf .multi_transfer /* no: next iteration */ |
294 | 294 | ||
295 | or #(LCD_CS|LCD_DS|LCD_SD|LCD_SC),r0 /* restore port */ | 295 | or #(LCD_CS|LCD_DS|LCD_SD|LCD_SC),r0 /* restore port */ |
296 | rts | 296 | rts |
297 | mov.b r0,@r3 | 297 | mov.b r0,@r3 |
298 | 298 | ||
299 | /* This is the place to reenable the interrupts, if we have disabled | 299 | /* This is the place to reenable the interrupts, if we have disabled |
@@ -305,70 +305,4 @@ _lcd_write_data: | |||
305 | 305 | ||
306 | .end: | 306 | .end: |
307 | .size _lcd_write_command,.end-_lcd_write_command | 307 | .size _lcd_write_command,.end-_lcd_write_command |
308 | #elif defined(IRIVER_H100_SERIES) | ||
309 | .section .icode,"ax",@progbits | ||
310 | |||
311 | .align 2 | ||
312 | .global lcd_write_command | ||
313 | .type lcd_write_command,@function | ||
314 | |||
315 | lcd_write_command: | ||
316 | move.l (4,%sp),%d0 | ||
317 | lea MBAR2,%a1 | ||
318 | move.l #~8,%d1 | ||
319 | and.l %d1,(0xb4,%a1) | ||
320 | move.w %d0,0xf0000000 | ||
321 | rts | ||
322 | |||
323 | .align 2 | ||
324 | .global lcd_write_command_ex | ||
325 | .type lcd_write_command_ex,@function | ||
326 | |||
327 | lcd_write_command_ex: | ||
328 | lea MBAR2,%a1 | ||
329 | |||
330 | move.l (4,%sp),%d0 /* Command */ | ||
331 | |||
332 | move.l #~8,%d1 /* Set A0 = 0 */ | ||
333 | and.l %d1,(0xb4,%a1) | ||
334 | move.w %d0,0xf0000000 /* Write to LCD */ | ||
335 | |||
336 | not.l %d1 /* Set A0 = 1 */ | ||
337 | or.l %d1,(0xb4,%a1) | ||
338 | |||
339 | move.l (8,%sp),%d0 /* Data */ | ||
340 | cmp.l #0xffffffff,%d0 /* -1? */ | ||
341 | beq.b .last | ||
342 | move.w %d0,0xf0000000 /* Write to LCD */ | ||
343 | |||
344 | move.l (12,%sp),%d0 /* Data */ | ||
345 | cmp.l #0xffffffff,%d0 /* -1? */ | ||
346 | beq.b .last | ||
347 | move.w %d0,0xf0000000 /* Write to LCD */ | ||
348 | |||
349 | .last: | ||
350 | rts | ||
351 | |||
352 | .align 2 | ||
353 | .global lcd_write_data | ||
354 | .type lcd_write_data,@function | ||
355 | |||
356 | lcd_write_data: | ||
357 | move.l (4,%sp),%a0 /* Data pointer */ | ||
358 | move.l (8,%sp),%d0 /* Length */ | ||
359 | lea MBAR2,%a1 | ||
360 | moveq #8,%d1 | ||
361 | or.l %d1,(0xb4,%a1) | ||
362 | |||
363 | lea 0xf0000000,%a1 | ||
364 | .loop: | ||
365 | /* When running in IRAM, this loop takes 7 cycles plus the LCD write. | ||
366 | The 7 cycles are necessary to follow the LCD timing specs | ||
367 | at 140MHz */ | ||
368 | move.b (%a0)+,%d1 /* 3(1/0) */ | ||
369 | move.w %d1,(%a1) /* 1(0/1) */ | ||
370 | subq.l #1,%d0 /* 1(0/0) */ | ||
371 | nop /* 1(0/0) */ | ||
372 | bne .loop /* 2(0/0) */ | ||
373 | rts | ||
374 | #endif | 308 | #endif |