summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd.S')
-rwxr-xr-xfirmware/drivers/lcd.S238
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
315lcd_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
327lcd_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
356lcd_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