summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/coldfire/iaudio/x5/lcd-as-x5.S115
-rwxr-xr-xfirmware/target/coldfire/iaudio/x5/lcd-x5.c24
2 files changed, 64 insertions, 75 deletions
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
index 7c89fb925e..54c1110d2a 100644
--- a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
+++ b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
@@ -290,6 +290,9 @@ lcd_write_yuv420_lines:
290 lea.l (36,%sp),%sp /* restore registers */ 290 lea.l (36,%sp),%sp /* restore registers */
291 291
292 rts 292 rts
293
294.yuv_end:
295 .size lcd_write_yuv420_lines,.yuv_end-lcd_write_yuv420_lines
293/* end lcd_write_yuv420_lines */ 296/* end lcd_write_yuv420_lines */
294 297
295 298
@@ -304,22 +307,19 @@ lcd_write_data:
304 add.l %a0,%d0 /* -> end address */ 307 add.l %a0,%d0 /* -> end address */
305 lea.l 0xf0008002,%a1 /* LCD data port */ 308 lea.l 0xf0008002,%a1 /* LCD data port */
306 309
307 lea.l (-24,%sp),%sp /* free up some registers */ 310 lea.l (-20,%sp),%sp /* free up some registers */
308 movem.l %d2-%d6/%a2,(%sp) 311 movem.l %d2-%d5/%a2,(%sp)
309 312
310 move.l %a0,%d1 313 move.l %a0,%d1
311 btst.l #1,%d1 /* already longword aligned? */ 314 btst.l #1,%d1 /* already longword aligned? */
312 beq.b .wd_wordl_end /* yes: skip initial word copy */ 315 beq.b .wd_wordl_end /* yes: skip initial word copy */
313 /* transfer initial word */ 316 /* transfer initial word */
314 move.w (%a0)+,%d1 /* |????????|????????|rrrrrggg|gggbbbbb| */ 317 move.w (%a0)+,%d2 /* |????????|????????|rrrrrggg|gggbbbbb| */
315 move.l %d1,%d2 318 move.l %d2,%d1
316 and.l #0xfffff800,%d2 /* |????????|????????|rrrrr000|00000000| */ 319 lsr.l #7,%d1 /* |0000000?|????????|???????r|rrrrgggg| */
317 add.l %d2,%d1 /* |????????|???????r|rrrr0ggg|gggbbbbb| */ 320 move.w %d1,(%a1) /* ^ ^^^^^^^ */
318 move.l %d1,%d2 321 lsl.l #1,%d2 /* |????????|???????r|rrrrgggg|ggbbbbb0| */
319 lsr.l #8,%d1 /* |00000000|????????|???????r|rrrr0ggg| */ 322 move.w %d2,(%a1) /* ^ ^^^^^^^ */
320 move.w %d1,(%a1)
321 lsl.l #1,%d2 /* |????????|??????rr|rrr0gggg|ggbbbbb0| */
322 move.w %d2,(%a1)
323 323
324.wd_wordl_end: /* now longword aligned */ 324.wd_wordl_end: /* now longword aligned */
325 moveq.l #28,%d1 325 moveq.l #28,%d1
@@ -335,22 +335,17 @@ lcd_write_data:
335 bls.b .wd_long1_end /* no: skip leading long loop */ 335 bls.b .wd_long1_end /* no: skip leading long loop */
336 336
337.wd_long1_loop: 337.wd_long1_loop:
338 move.l (%a0)+,%d2 /* read longword */ 338 move.l (%a0)+,%d2 /* read longword */
339 swap %d2 /* unstuff two pixels and correct order */ 339 swap %d2 /* |rrrrrggg|gggbbbbb|RRRRRGGG|GGGBBBBB| */
340 move.l %d2,%d5 340 move.l %d2,%d5
341 and.l #0xff00ff00,%d5 /* |rrrrrggg|00000000|rrrrrggg|00000000| */ 341 lsr.l #7,%d5 /* |0000000r|rrrrgggg|ggbbbbbR|RRRRGGGG| */
342 eor.l %d5,%d2 /* |00000000|gggbbbbb|00000000|gggbbbbb| */ 342 move.w %d5,(%a1) /* ^ ^^^^^^^ */
343 lsr.l #8,%d5 /* |00000000|rrrrrggg|00000000|rrrrrggg| */ 343 lsl.l #1,%d2 /* |rrrrgggg|ggbbbbbR|RRRRBGGG|GGBBBBB0| */
344 move.l %d5,%d6 344 move.w %d2,(%a1) /* ^ ^^^^^^^ */
345 and.l #0x00f800f8,%d5 /* |00000000|rrrrr000|00000000|rrrrr000| */ 345 swap %d5 /* |ggbbbbbR|RRRRGGGG|0000000r|rrrrgggg| */
346 add.l %d6,%d5 /* |0000000r|rrrr0ggg|0000000r|rrrr0ggg| */ 346 move.w %d5,(%a1) /* ^ ^^^^^^^ */
347 move.w %d5,(%a1) 347 swap %d2 /* |RRRRBGGG|GGBBBBB0|rrrrgggg|ggbbbbbR| */
348 lsl.l #1,%d2 /* |0000000g|ggbbbbb0|0000000g|ggbbbbb0| */ 348 move.w %d2,(%a1) /* ^ ^^^^^^^ */
349 move.w %d2,(%a1)
350 swap %d5
351 move.w %d5,(%a1)
352 swap %d2
353 move.w %d2,(%a1)
354 cmp.l %a0,%d1 349 cmp.l %a0,%d1
355 bhi.b .wd_long1_loop 350 bhi.b .wd_long1_loop
356 351
@@ -363,15 +358,9 @@ lcd_write_data:
363 lea.l (16,%a0),%a0 /* increment address */ 358 lea.l (16,%a0),%a0 /* increment address */
364 359
365 /* transfer four pairs of longs to display */ 360 /* transfer four pairs of longs to display */
366 /* same procedure for each as in leading long loop */
367 swap %d1 361 swap %d1
368 move.l %d1,%d5 362 move.l %d1,%d5
369 and.l #0xff00ff00,%d5 363 lsr.l #7,%d5
370 eor.l %d5,%d1
371 lsr.l #8,%d5
372 move.l %d5,%d6
373 and.l #0x00f800f8,%d5
374 add.l %d6,%d5
375 move.w %d5,(%a1) 364 move.w %d5,(%a1)
376 lsl.l #1,%d1 365 lsl.l #1,%d1
377 move.w %d1,(%a1) 366 move.w %d1,(%a1)
@@ -380,14 +369,9 @@ lcd_write_data:
380 swap %d1 369 swap %d1
381 move.w %d1,(%a1) 370 move.w %d1,(%a1)
382 371
383 swap %d2 372 swap %d2
384 move.l %d2,%d5 373 move.l %d2,%d5
385 and.l #0xff00ff00,%d5 374 lsr.l #7,%d5
386 eor.l %d5,%d2
387 lsr.l #8,%d5
388 move.l %d5,%d6
389 and.l #0x00f800f8,%d5
390 add.l %d6,%d5
391 move.w %d5,(%a1) 375 move.w %d5,(%a1)
392 lsl.l #1,%d2 376 lsl.l #1,%d2
393 move.w %d2,(%a1) 377 move.w %d2,(%a1)
@@ -396,14 +380,9 @@ lcd_write_data:
396 swap %d2 380 swap %d2
397 move.w %d2,(%a1) 381 move.w %d2,(%a1)
398 382
399 swap %d3 383 swap %d3
400 move.l %d3,%d5 384 move.l %d3,%d5
401 and.l #0xff00ff00,%d5 385 lsr.l #7,%d5
402 eor.l %d5,%d3
403 lsr.l #8,%d5
404 move.l %d5,%d6
405 and.l #0x00f800f8,%d5
406 add.l %d6,%d5
407 move.w %d5,(%a1) 386 move.w %d5,(%a1)
408 lsl.l #1,%d3 387 lsl.l #1,%d3
409 move.w %d3,(%a1) 388 move.w %d3,(%a1)
@@ -412,14 +391,9 @@ lcd_write_data:
412 swap %d3 391 swap %d3
413 move.w %d3,(%a1) 392 move.w %d3,(%a1)
414 393
415 swap %d4 394 swap %d4
416 move.l %d4,%d5 395 move.l %d4,%d5
417 and.l #0xff00ff00,%d5 396 lsr.l #7,%d5
418 eor.l %d5,%d4
419 lsr.l #8,%d5
420 move.l %d5,%d6
421 and.l #0x00f800f8,%d5
422 add.l %d6,%d5
423 move.w %d5,(%a1) 397 move.w %d5,(%a1)
424 lsl.l #1,%d4 398 lsl.l #1,%d4
425 move.w %d4,(%a1) 399 move.w %d4,(%a1)
@@ -437,15 +411,10 @@ lcd_write_data:
437 bls.b .wd_long2_end /* no: skip trailing longword loop */ 411 bls.b .wd_long2_end /* no: skip trailing longword loop */
438 412
439.wd_long2_loop: 413.wd_long2_loop:
440 move.l (%a0)+,%d2 /* read longword */ 414 move.l (%a0)+,%d2 /* read longword */
441 swap %d2 415 swap %d2
442 move.l %d2,%d5 416 move.l %d2,%d5
443 and.l #0xff00ff00,%d5 417 lsr.l #7,%d5
444 eor.l %d5,%d2
445 lsr.l #8,%d5
446 move.l %d5,%d6
447 and.l #0x00f800f8,%d5
448 add.l %d6,%d5
449 move.w %d5,(%a1) 418 move.w %d5,(%a1)
450 lsl.l #1,%d2 419 lsl.l #1,%d2
451 move.w %d2,(%a1) 420 move.w %d2,(%a1)
@@ -459,18 +428,18 @@ lcd_write_data:
459.wd_long2_end: 428.wd_long2_end:
460 blo.b .wd_word2_end /* no final word: skip */ 429 blo.b .wd_word2_end /* no final word: skip */
461 430
462 move.w (%a0),%d1 /* transfer final word */ 431 move.w (%a0)+,%d2 /* transfer final word */
463 move.l %d1,%d2 432 move.l %d2,%d1
464 and.l #0xfffff800,%d2 433 lsr.l #7,%d1
465 add.l %d2,%d1 434 move.w %d1,(%a1)
466 move.l %d1,%d2 435 lsl.l #1,%d2
467 lsr.l #8,%d1 436 move.w %d2,(%a1)
468 move.w %d1,(%a1)
469 lsl.l #1,%d2
470 move.w %d2,(%a1)
471 437
472.wd_word2_end: 438.wd_word2_end:
473 movem.l (%sp),%d2-%d6/%a2 439 movem.l (%sp),%d2-%d5/%a2
474 lea.l (24,%sp),%sp /* restore registers */ 440 lea.l (20,%sp),%sp /* restore registers */
475 rts 441 rts
442
443.wd_end:
444 .size lcd_write_data,.wd_end-lcd_write_data
476/* end lcd_write_data */ 445/* end lcd_write_data */
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-x5.c b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
index c00dc74b0c..e1fac1e2ac 100755
--- a/firmware/target/coldfire/iaudio/x5/lcd-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
@@ -44,6 +44,9 @@ static unsigned short disp_control_rev;
44/* Contrast setting << 8 */ 44/* Contrast setting << 8 */
45static int lcd_contrast; 45static int lcd_contrast;
46 46
47/* Hardware dither bit */
48static unsigned short hw_dit = 0x0000;
49
47/* Forward declarations */ 50/* Forward declarations */
48static void lcd_display_off(void); 51static void lcd_display_off(void);
49 52
@@ -102,6 +105,13 @@ static inline void lcd_begin_write_gram(void)
102 LCD_CMD = R_WRITE_DATA_2_GRAM << 1; 105 LCD_CMD = R_WRITE_DATA_2_GRAM << 1;
103} 106}
104 107
108static void hw_dither(bool on)
109{
110 /* DIT=x, BGR=1, HWM=0, I/D1-0=11, AM=1, LG2-0=000 */
111 hw_dit = on ? 0x8000 : 0x0000;
112 lcd_write_reg(R_ENTRY_MODE, 0x1038 | hw_dit);
113}
114
105/*** hardware configuration ***/ 115/*** hardware configuration ***/
106 116
107int lcd_default_contrast(void) 117int lcd_default_contrast(void)
@@ -224,8 +234,8 @@ static void lcd_power_on(void)
224 lcd_write_reg(R_DRV_OUTPUT_CONTROL, y_offset ? 0x0013 : 0x0313); 234 lcd_write_reg(R_DRV_OUTPUT_CONTROL, y_offset ? 0x0013 : 0x0313);
225 /* FLD1-0=01 (1 field), B/C=1, EOR=1 (C-pat), NW5-0=000000 (1 row) */ 235 /* FLD1-0=01 (1 field), B/C=1, EOR=1 (C-pat), NW5-0=000000 (1 row) */
226 lcd_write_reg(R_DRV_AC_CONTROL, 0x0700); 236 lcd_write_reg(R_DRV_AC_CONTROL, 0x0700);
227 /* DIT=1, BGR=1, HWM=0, I/D1-0=11, AM=1, LG2-0=000 */ 237 /* DIT=x, BGR=1, HWM=0, I/D1-0=11, AM=1, LG2-0=000 */
228 lcd_write_reg(R_ENTRY_MODE, 0x9038); 238 lcd_write_reg(R_ENTRY_MODE, 0x1038 | hw_dit);
229 /* CP15-0=0000000000000000 */ 239 /* CP15-0=0000000000000000 */
230 lcd_write_reg(R_COMPARE_REG, 0x0000); 240 lcd_write_reg(R_COMPARE_REG, 0x0000);
231 /* NO1-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-00000 */ 241 /* NO1-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-00000 */
@@ -379,6 +389,7 @@ void lcd_init_device(void)
379 lcd_roll(0); 389 lcd_roll(0);
380 lcd_set_invert_display(false); 390 lcd_set_invert_display(false);
381 lcd_set_contrast(DEFAULT_CONTRAST_SETTING); 391 lcd_set_contrast(DEFAULT_CONTRAST_SETTING);
392 hw_dither(false); /* do this or all bootloaders will need reflashing */
382#endif 393#endif
383} 394}
384 395
@@ -455,6 +466,9 @@ void lcd_yuv_blit(unsigned char * const src[3],
455 if (!display_on) 466 if (!display_on)
456 return; 467 return;
457 468
469 if (hw_dit == 0x0000)
470 hw_dither(true);
471
458 width = (width + 1) & ~1; 472 width = (width + 1) & ~1;
459 height = (height + 1) & ~1; 473 height = (height + 1) & ~1;
460 474
@@ -493,6 +507,9 @@ void lcd_update(void)
493 if (!display_on) 507 if (!display_on)
494 return; 508 return;
495 509
510 if (hw_dit != 0x0000)
511 hw_dither(false);
512
496 /* Set start position and window */ 513 /* Set start position and window */
497 /* Just add roll offset to start address. CP will roll back around. */ 514 /* Just add roll offset to start address. CP will roll back around. */
498 lcd_write_reg(R_RAM_ADDR_SET, y_offset + roll_offset); /* X == 0 */ 515 lcd_write_reg(R_RAM_ADDR_SET, y_offset + roll_offset); /* X == 0 */
@@ -513,6 +530,9 @@ void lcd_update_rect(int x, int y, int width, int height)
513 if (!display_on) 530 if (!display_on)
514 return; 531 return;
515 532
533 if (hw_dit != 0x0000)
534 hw_dither(false);
535
516 if (x + width > LCD_WIDTH) 536 if (x + width > LCD_WIDTH)
517 width = LCD_WIDTH - x; /* Clip right */ 537 width = LCD_WIDTH - x; /* Clip right */
518 if (x < 0) 538 if (x < 0)