summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire')
-rw-r--r--firmware/target/coldfire/iaudio/m5/lcd-as-m5.S93
-rw-r--r--firmware/target/coldfire/iaudio/m5/lcd-m5.c15
-rw-r--r--firmware/target/coldfire/iriver/h100/lcd-as-h100.S120
-rw-r--r--firmware/target/coldfire/iriver/h100/lcd-h100.c15
4 files changed, 198 insertions, 45 deletions
diff --git a/firmware/target/coldfire/iaudio/m5/lcd-as-m5.S b/firmware/target/coldfire/iaudio/m5/lcd-as-m5.S
index 4a88dc92b0..7e89815ec8 100644
--- a/firmware/target/coldfire/iaudio/m5/lcd-as-m5.S
+++ b/firmware/target/coldfire/iaudio/m5/lcd-as-m5.S
@@ -41,18 +41,18 @@ lcd_write_command:
41lcd_write_command_ex: 41lcd_write_command_ex:
42 lea.l 0xf0008000, %a0 42 lea.l 0xf0008000, %a0
43 43
44 move.l (4, %sp), %d0 /* Command */ 44 move.l (4, %sp), %d0 /* Command */
45 move.w %d0, (%a0)+ /* Write to LCD, set A0 = 1 */ 45 move.w %d0, (%a0)+ /* Write to LCD, set A0 = 1 */
46 46
47 move.l (8, %sp), %d0 /* Data */ 47 move.l (8, %sp), %d0 /* Data */
48 cmp.l #-1, %d0 /* -1? */ 48 cmp.l #-1, %d0 /* -1? */
49 beq.b .last 49 beq.b .last
50 move.w %d0, (%a0) /* Write to LCD */ 50 move.w %d0, (%a0) /* Write to LCD */
51 51
52 move.l (12, %sp), %d0 /* Data */ 52 move.l (12, %sp), %d0 /* Data */
53 cmp.l #-1, %d0 /* -1? */ 53 cmp.l #-1, %d0 /* -1? */
54 beq.b .last 54 beq.b .last
55 move.w %d0, (%a0) /* Write to LCD */ 55 move.w %d0, (%a0) /* Write to LCD */
56 56
57.last: 57.last:
58 rts 58 rts
@@ -65,19 +65,80 @@ lcd_write_command_ex:
65 .type lcd_write_data,@function 65 .type lcd_write_data,@function
66 66
67lcd_write_data: 67lcd_write_data:
68 move.l (4,%sp), %a0 /* Data pointer */ 68 movem.l (4, %sp), %a0-%a1 /* Data pointer */
69 move.l (8,%sp), %d0 /* Length */ 69 move.l %a1, %d0 /* Length */
70
71 lea 0xf0008002, %a1 70 lea 0xf0008002, %a1
71
72.loop: 72.loop:
73 /* When running in IRAM, this loop takes 10 cycles plus the LCD write. 73 /* When running in IRAM, this loop takes 10 cycles plus the LCD write.
74 The 10 cycles are necessary to follow the LCD timing specs 74 The 10 cycles are necessary to follow the LCD timing specs
75 at 140MHz */ 75 at 140MHz */
76 nop /* 3(0/0) */ 76 nop /* 3(0/0) */
77 move.b (%a0)+, %d1 /* 3(1/0) */ 77 move.b (%a0)+, %d1 /* 3(1/0) */
78 move.w %d1, (%a1) /* 1(0/1) */ 78 move.w %d1, (%a1) /* 1(0/1) */
79 subq.l #1, %d0 /* 1(0/0) */ 79 subq.l #1, %d0 /* 1(0/0) */
80 bne .loop /* 2(0/0) */ 80 bne .loop /* 2(0/0) */
81 rts 81 rts
82.wd_end: 82.wd_end:
83 .size lcd_write_data,.wd_end-lcd_write_data 83 .size lcd_write_data,.wd_end-lcd_write_data
84
85
86 .align 2
87 .global lcd_grey_data
88 .type lcd_grey_data,@function
89
90lcd_grey_data:
91 lea.l (-4*4, %sp), %sp
92 movem.l %d2-%d5, (%sp)
93 movem.l (4*4+4, %sp), %a0-%a1 /* Data pointer */
94 move.l %a1, %d0 /* Length */
95 lea 0xf0008002, %a1 /* LCD data port */
96 move.l #0xff00ff00, %d2 /* mask for splitting value/phase pairs */
97
98.greyloop:
99 movem.l (%a0), %d4-%d5 /* fetch 4 pixel phase/value pairs at once */
100 /* %d4 = p0v0p1v1, %d5 = p2v2p3v3 */
101 move.l %d2, %d3 /* copy mask */
102 and.l %d4, %d3 /* %d3 = p0--p1-- */
103 eor.l %d3, %d4 /* %d4 = --v0--v1 */
104 lsr.l #8, %d3 /* %d3 = --p0--p1 */
105
106 bclr.l #23, %d3 /* Z = !(p0 & 0x80); p0 &= ~0x80; */
107 seq.b %d1 /* %d1 = ........................00000000 */
108 lsl.l #2, %d1 /* %d1 = ......................00000000.. */
109 bclr.l #7, %d3 /* Z = !(p1 & 0x80); p1 &= ~0x80; */
110 seq.b %d1 /* %d1 = ......................0011111111 */
111 lsl.l #2, %d1 /* %d1 = ....................0011111111.. */
112
113 add.l %d4, %d3 /* p0 += v0; p1 += v1; */
114 move.b %d3, (2, %a0) /* store p1 */
115 swap %d3
116 move.b %d3, (%a0) /* store p0 */
117
118 move.l %d2, %d3 /* copy mask */
119 and.l %d5, %d3 /* %d3 = p2--p3-- */
120 eor.l %d3, %d5 /* %d5 = --v2--v3 */
121 lsr.l #8, %d3 /* %d3 = --p2--p3 */
122
123 bclr.l #23, %d3 /* Z = !(p2 & 0x80); p2 &= ~0x80; */
124 seq.b %d1 /* %d1 = ....................001122222222 */
125 lsl.l #2, %d1 /* %d1 = ..................001122222222.. */
126 bclr.l #7, %d3 /* Z = !(p3 & 0x80); p3 &= ~0x80; */
127 seq.b %d1 /* %d1 = ..................00112233333333 */
128 lsr.l #6, %d1 /* %d1 = ........................00112233 */
129
130 add.l %d5, %d3 /* p2 += v2; p3 += v3; */
131 move.b %d3, (6, %a0) /* store p3 */
132 swap %d3
133 move.b %d3, (4, %a0) /* store p2 */
134
135 move.w %d1, (%a1) /* write pixel block */
136 addq.l #8, %a0 /* advance address pointer */
137 subq.l #1, %d0 /* any blocks left? */
138 bne.b .greyloop
139
140 movem.l (%sp), %d2-%d5
141 lea.l (4*4, %sp), %sp
142 rts
143.gd_end:
144 .size lcd_grey_data,.gd_end-lcd_grey_data
diff --git a/firmware/target/coldfire/iaudio/m5/lcd-m5.c b/firmware/target/coldfire/iaudio/m5/lcd-m5.c
index 2af46b3145..4f963795c7 100644
--- a/firmware/target/coldfire/iaudio/m5/lcd-m5.c
+++ b/firmware/target/coldfire/iaudio/m5/lcd-m5.c
@@ -171,6 +171,21 @@ void lcd_blit(const unsigned char* data, int x, int by, int width,
171 } 171 }
172} 172}
173 173
174/* Performance function that works with an external buffer
175 note that by and bheight are in 4-pixel units! */
176void lcd_grey_phase_blit(const struct grey_data *data, int x, int by,
177 int width, int bheight, int stride)
178{
179 stride <<= 2; /* 4 pixels per block */
180 while (bheight--)
181 {
182 lcd_write_command_ex(LCD_CNTL_PAGE, by++, -1);
183 lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1);
184 lcd_write_command(LCD_CNTL_DATA_WRITE);
185 lcd_grey_data(data, width);
186 data += stride;
187 }
188}
174 189
175/* Update the display. 190/* Update the display.
176 This must be called after all other LCD functions that change the display. */ 191 This must be called after all other LCD functions that change the display. */
diff --git a/firmware/target/coldfire/iriver/h100/lcd-as-h100.S b/firmware/target/coldfire/iriver/h100/lcd-as-h100.S
index c7509871fc..df410fa379 100644
--- a/firmware/target/coldfire/iriver/h100/lcd-as-h100.S
+++ b/firmware/target/coldfire/iriver/h100/lcd-as-h100.S
@@ -28,11 +28,10 @@
28 .type lcd_write_command,@function 28 .type lcd_write_command,@function
29 29
30lcd_write_command: 30lcd_write_command:
31 move.l (4,%sp),%d0 31 move.l #~8, %d1
32 lea MBAR2,%a1 32 and.l %d1, (MBAR2+0xb4)
33 move.l #~8,%d1 33 move.l (4, %sp), %d0
34 and.l %d1,(0xb4,%a1) 34 move.w %d0, 0xf0000000
35 move.w %d0,0xf0000000
36 rts 35 rts
37.wc_end: 36.wc_end:
38 .size lcd_write_command,.wc_end-lcd_write_command 37 .size lcd_write_command,.wc_end-lcd_write_command
@@ -43,26 +42,27 @@ lcd_write_command:
43 .type lcd_write_command_ex,@function 42 .type lcd_write_command_ex,@function
44 43
45lcd_write_command_ex: 44lcd_write_command_ex:
46 lea MBAR2,%a1 45 lea.l 0xf0000000, %a0
46 lea.l MBAR2+0xb4, %a1
47 47
48 move.l (4,%sp),%d0 /* Command */ 48 move.l #~8, %d1 /* Set A0 = 0 */
49 and.l %d1, (%a1)
49 50
50 move.l #~8,%d1 /* Set A0 = 0 */ 51 move.l (4, %sp), %d0 /* Command */
51 and.l %d1,(0xb4,%a1) 52 move.w %d0, (%a0) /* Write to LCD */
52 move.w %d0,0xf0000000 /* Write to LCD */
53 53
54 not.l %d1 /* Set A0 = 1 */ 54 not.l %d1 /* Set A0 = 1 */
55 or.l %d1,(0xb4,%a1) 55 or.l %d1, (%a1)
56 56
57 move.l (8,%sp),%d0 /* Data */ 57 move.l (8, %sp), %d0 /* Data */
58 cmp.l #0xffffffff,%d0 /* -1? */ 58 cmp.l #-1, %d0 /* -1? */
59 beq.b .last 59 beq.b .last
60 move.w %d0,0xf0000000 /* Write to LCD */ 60 move.w %d0, (%a0) /* Write to LCD */
61 61
62 move.l (12,%sp),%d0 /* Data */ 62 move.l (12, %sp), %d0 /* Data */
63 cmp.l #0xffffffff,%d0 /* -1? */ 63 cmp.l #-1, %d0 /* -1? */
64 beq.b .last 64 beq.b .last
65 move.w %d0,0xf0000000 /* Write to LCD */ 65 move.w %d0, (%a0) /* Write to LCD */
66 66
67.last: 67.last:
68 rts 68 rts
@@ -75,22 +75,84 @@ lcd_write_command_ex:
75 .type lcd_write_data,@function 75 .type lcd_write_data,@function
76 76
77lcd_write_data: 77lcd_write_data:
78 move.l (4,%sp),%a0 /* Data pointer */ 78 movem.l (4, %sp), %a0-%a1 /* Data pointer */
79 move.l (8,%sp),%d0 /* Length */ 79 move.l %a1, %d0 /* Length */
80 lea MBAR2,%a1 80 moveq #8, %d1
81 moveq #8,%d1 81 or.l %d1, (MBAR2+0xb4)
82 or.l %d1,(0xb4,%a1) 82 lea.l 0xf0000000, %a1
83 83
84 lea 0xf0000000,%a1
85.loop: 84.loop:
86 /* When running in IRAM, this loop takes 10 cycles plus the LCD write. 85 /* When running in IRAM, this loop takes 10 cycles plus the LCD write.
87 The 10 cycles are necessary to follow the LCD timing specs 86 The 10 cycles are necessary to follow the LCD timing specs
88 at 140MHz */ 87 at 140MHz */
89 nop /* 3(0/0) */ 88 nop /* 3(0/0) */
90 move.b (%a0)+,%d1 /* 3(1/0) */ 89 move.b (%a0)+, %d1 /* 3(1/0) */
91 move.w %d1,(%a1) /* 1(0/1) */ 90 move.w %d1, (%a1) /* 1(0/1) */
92 subq.l #1,%d0 /* 1(0/0) */ 91 subq.l #1, %d0 /* 1(0/0) */
93 bne .loop /* 2(0/0) */ 92 bne .loop /* 2(0/0) */
94 rts 93 rts
95.wd_end: 94.wd_end:
96 .size lcd_write_data,.wd_end-lcd_write_data 95 .size lcd_write_data,.wd_end-lcd_write_data
96
97
98 .align 2
99 .global lcd_grey_data
100 .type lcd_grey_data,@function
101
102lcd_grey_data:
103 lea.l (-4*4, %sp), %sp
104 movem.l %d2-%d5, (%sp)
105 movem.l (4*4+4, %sp), %a0-%a1 /* Data pointer */
106 move.l %a1, %d0 /* Length */
107 moveq #8, %d1
108 or.l %d1, (MBAR2+0xb4) /* A0 = 1 (data) */
109 lea 0xf0000000, %a1 /* LCD data port */
110 move.l #0xff00ff00, %d2 /* mask for splitting value/phase pairs */
111
112.greyloop:
113 movem.l (%a0), %d4-%d5 /* fetch 4 pixel phase/value pairs at once */
114 /* %d4 = p0v0p1v1, %d5 = p2v2p3v3 */
115 move.l %d2, %d3 /* copy mask */
116 and.l %d4, %d3 /* %d3 = p0--p1-- */
117 eor.l %d3, %d4 /* %d4 = --v0--v1 */
118 lsr.l #8, %d3 /* %d3 = --p0--p1 */
119
120 bclr.l #23, %d3 /* Z = !(p0 & 0x80); p0 &= ~0x80; */
121 seq.b %d1 /* %d1 = ........................00000000 */
122 lsl.l #2, %d1 /* %d1 = ......................00000000.. */
123 bclr.l #7, %d3 /* Z = !(p1 & 0x80); p1 &= ~0x80; */
124 seq.b %d1 /* %d1 = ......................0011111111 */
125 lsl.l #2, %d1 /* %d1 = ....................0011111111.. */
126
127 add.l %d4, %d3 /* p0 += v0; p1 += v1; */
128 move.b %d3, (2, %a0) /* store p1 */
129 swap %d3
130 move.b %d3, (%a0) /* store p0 */
131
132 move.l %d2, %d3 /* copy mask */
133 and.l %d5, %d3 /* %d3 = p2--p3-- */
134 eor.l %d3, %d5 /* %d5 = --v2--v3 */
135 lsr.l #8, %d3 /* %d3 = --p2--p3 */
136
137 bclr.l #23, %d3 /* Z = !(p2 & 0x80); p2 &= ~0x80; */
138 seq.b %d1 /* %d1 = ....................001122222222 */
139 lsl.l #2, %d1 /* %d1 = ..................001122222222.. */
140 bclr.l #7, %d3 /* Z = !(p3 & 0x80); p3 &= ~0x80; */
141 seq.b %d1 /* %d1 = ..................00112233333333 */
142 lsr.l #6, %d1 /* %d1 = ........................00112233 */
143
144 add.l %d5, %d3 /* p2 += v2; p3 += v3; */
145 move.b %d3, (6, %a0) /* store p3 */
146 swap %d3
147 move.b %d3, (4, %a0) /* store p2 */
148
149 move.w %d1, (%a1) /* write pixel block */
150 addq.l #8, %a0 /* advance address pointer */
151 subq.l #1, %d0 /* any blocks left? */
152 bne.b .greyloop
153
154 movem.l (%sp), %d2-%d5
155 lea.l (4*4, %sp), %sp
156 rts
157.gd_end:
158 .size lcd_grey_data,.gd_end-lcd_grey_data
diff --git a/firmware/target/coldfire/iriver/h100/lcd-h100.c b/firmware/target/coldfire/iriver/h100/lcd-h100.c
index a721273384..c17de952c3 100644
--- a/firmware/target/coldfire/iriver/h100/lcd-h100.c
+++ b/firmware/target/coldfire/iriver/h100/lcd-h100.c
@@ -180,6 +180,21 @@ void lcd_blit(const unsigned char* data, int x, int by, int width,
180 } 180 }
181} 181}
182 182
183/* Performance function that works with an external buffer
184 note that by and bheight are in 4-pixel units! */
185void lcd_grey_phase_blit(const struct grey_data *data, int x, int by,
186 int width, int bheight, int stride)
187{
188 stride <<= 2; /* 4 pixels per block */
189 while (bheight--)
190 {
191 lcd_write_command_ex(LCD_CNTL_PAGE, by++, -1);
192 lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1);
193 lcd_write_command(LCD_CNTL_DATA_WRITE);
194 lcd_grey_data(data, width);
195 data += stride;
196 }
197}
183 198
184/* Update the display. 199/* Update the display.
185 This must be called after all other LCD functions that change the display. */ 200 This must be called after all other LCD functions that change the display. */