summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd.S')
-rwxr-xr-xfirmware/drivers/lcd.S161
1 files changed, 117 insertions, 44 deletions
diff --git a/firmware/drivers/lcd.S b/firmware/drivers/lcd.S
index 79c6e32f33..2b50de5190 100755
--- a/firmware/drivers/lcd.S
+++ b/firmware/drivers/lcd.S
@@ -313,62 +313,135 @@ _lcd_write_data:
313 .type lcd_write_command,@function 313 .type lcd_write_command,@function
314 314
315lcd_write_command: 315lcd_write_command:
316 move.l (4,%sp),%d0 316 move.l (4,%sp),%d0
317 lea MBAR2,%a1 317 lea MBAR2,%a1
318 move.l #~8,%d1 318 move.l #~8,%d1
319 and.l %d1,(0xb4,%a1) 319 and.l %d1,(0xb4,%a1)
320 move.w %d0,0xf0000000 320 move.w %d0,0xf0000000
321 rts 321 rts
322 322
323 .align 2 323 .align 2
324 .global lcd_write_command_ex 324 .global lcd_write_command_ex
325 .type lcd_write_command_ex,@function 325 .type lcd_write_command_ex,@function
326 326
327lcd_write_command_ex: 327lcd_write_command_ex:
328 lea MBAR2,%a1 328 lea MBAR2,%a1
329 329
330 move.l (4,%sp),%d0 /* Command */ 330 move.l (4,%sp),%d0 /* Command */
331 331
332 move.l #~8,%d1 /* Set A0 = 0 */ 332 move.l #~8,%d1 /* Set A0 = 0 */
333 and.l %d1,(0xb4,%a1) 333 and.l %d1,(0xb4,%a1)
334 move.w %d0,0xf0000000 /* Write to LCD */ 334 move.w %d0,0xf0000000 /* Write to LCD */
335 335
336 not.l %d1 /* Set A0 = 1 */ 336 not.l %d1 /* Set A0 = 1 */
337 or.l %d1,(0xb4,%a1) 337 or.l %d1,(0xb4,%a1)
338 338
339 move.l (8,%sp),%d0 /* Data */ 339 move.l (8,%sp),%d0 /* Data */
340 cmp.l #0xffffffff,%d0 /* -1? */ 340 cmp.l #0xffffffff,%d0 /* -1? */
341 beq.b .last 341 beq.b .last
342 move.w %d0,0xf0000000 /* Write to LCD */ 342 move.w %d0,0xf0000000 /* Write to LCD */
343 343
344 move.l (12,%sp),%d0 /* Data */ 344 move.l (12,%sp),%d0 /* Data */
345 cmp.l #0xffffffff,%d0 /* -1? */ 345 cmp.l #0xffffffff,%d0 /* -1? */
346 beq.b .last 346 beq.b .last
347 move.w %d0,0xf0000000 /* Write to LCD */ 347 move.w %d0,0xf0000000 /* Write to LCD */
348 348
349.last: 349.last:
350 rts 350 rts
351 351
352 .align 2 352 .align 2
353 .global lcd_write_data 353 .global lcd_write_data
354 .type lcd_write_data,@function 354 .type lcd_write_data,@function
355 355
356lcd_write_data: 356lcd_write_data:
357 move.l (4,%sp),%a0 /* Data pointer */ 357 move.l (4,%sp),%a0 /* Data pointer */
358 move.l (8,%sp),%d0 /* Length */ 358 move.l (8,%sp),%d0 /* Length */
359 lea MBAR2,%a1 359 lea MBAR2,%a1
360 moveq #8,%d1 360 moveq #8,%d1
361 or.l %d1,(0xb4,%a1) 361 or.l %d1,(0xb4,%a1)
362 362
363 lea 0xf0000000,%a1 363 lea 0xf0000000,%a1
364.loop: 364.loop:
365 /* When running in IRAM, this loop takes 7 cycles plus the LCD write. 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 366 The 7 cycles are necessary to follow the LCD timing specs
367 at 140MHz */ 367 at 140MHz */
368 move.b (%a0)+,%d1 /* 3(1/0) */ 368 move.b (%a0)+,%d1 /* 3(1/0) */
369 move.w %d1,(%a1) /* 1(0/1) */ 369 move.w %d1,(%a1) /* 1(0/1) */
370 subq.l #1,%d0 /* 1(0/0) */ 370 subq.l #1,%d0 /* 1(0/0) */
371 nop /* 1(0/0) */ 371 nop /* 1(0/0) */
372 bne .loop /* 2(0/0) */ 372 bne .loop /* 2(0/0) */
373 rts 373 rts
374#elif defined(IRIVER_H300_SERIES)
375 .section .icode,"ax",@progbits
376
377 .align 2
378 .global lcd_write_data
379 .type lcd_write_data,@function
380
381lcd_write_data:
382 move.l (4,%sp),%a0 /* data pointer */
383 move.l (8,%sp),%d0 /* length in words */
384 add.l %d0,%d0 /* words -> bytes */
385 add.l %a0,%d0 /* -> end address */
386 lea.l 0xf0000002,%a1 /* LCD data port */
387
388 moveq.l #31,%d1
389 add.l %a0,%d1
390 and.l #0xFFFFFFF0,%d1 /* %d1 = first line bound + 16 */
391 cmp.l %d1,%d0 /* at least one full line to send? */
392 blo.b .words2_loop /* no: skip to word loop */
393
394 subq.l #8,%d1
395 subq.l #8,%d1 /* %d1 = first line bound */
396
397 cmp.l %a0,%d1 /* any leading words? */
398 bls.b .words1_end /* no: skip leading word loop */
399
400.words1_loop:
401 move.w (%a0)+,(%a1) /* transfer word */
402 cmp.l %a0,%d1 /* run %a0 up to first line bound */
403 bhi.b .words1_loop
404
405.words1_end:
406 lea.l (-16,%sp),%sp /* free up some registers */
407 movem.l %d2-%d4/%a2,(%sp)
408 move.l %d0,%a2
409 lea.l (-15,%a2),%a2 /* %a2 = end address - 15 (one line/pass) */
410
411 /* burst-optimised line transfers */
412.line_loop:
413 movem.l (%a0),%d1-%d4 /* burst-read line */
414 lea.l (16,%a0),%a0 /* increment address */
415 swap %d1 /* send data to LCD in correct order... */
416 move.w %d1,(%a1)
417 swap %d1
418 move.w %d1,(%a1)
419 swap %d2
420 move.w %d2,(%a1)
421 swap %d2
422 move.w %d2,(%a1)
423 swap %d3
424 move.w %d3,(%a1)
425 swap %d3
426 move.w %d3,(%a1)
427 swap %d4
428 move.w %d4,(%a1)
429 swap %d4
430 move.w %d4,(%a1)
431 cmp.l %a0,%a2 /* run %a0 up to last line bound */
432 bhi.b .line_loop
433
434 movem.l (%sp),%d2-%d4/%a2
435 lea.l (16,%sp),%sp /* restore registers */
436
437 cmp.l %a0,%d0 /* any trailing words? */
438 bls.b .words2_end /* no: get otta here */
439
440.words2_loop:
441 move.w (%a0)+,(%a1) /* transfer word */
442 cmp.l %a0,%d0 /* run %a0 up to end address */
443 bhi.b .words2_loop
444
445.words2_end:
446 rts
374#endif 447#endif