diff options
Diffstat (limited to 'firmware/target/coldfire/mpio/hd300/lcd-as-hd300.S')
-rw-r--r-- | firmware/target/coldfire/mpio/hd300/lcd-as-hd300.S | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/firmware/target/coldfire/mpio/hd300/lcd-as-hd300.S b/firmware/target/coldfire/mpio/hd300/lcd-as-hd300.S new file mode 100644 index 0000000000..e5b04001dc --- /dev/null +++ b/firmware/target/coldfire/mpio/hd300/lcd-as-hd300.S | |||
@@ -0,0 +1,227 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Adopted for MPIO HD300 by Marcin Bukat | ||
11 | * Copyright (C) 2007 by Jens Arnold | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include "config.h" | ||
24 | #include "cpu.h" | ||
25 | |||
26 | .section .icode,"ax",@progbits | ||
27 | |||
28 | .align 2 | ||
29 | .global lcd_write_command | ||
30 | .type lcd_write_command,@function | ||
31 | |||
32 | lcd_write_command: | ||
33 | move.l (4, %sp), %d0 | ||
34 | move.w %d0, 0xf0000000 | ||
35 | rts | ||
36 | .wc_end: | ||
37 | .size lcd_write_command,.wc_end-lcd_write_command | ||
38 | |||
39 | |||
40 | .align 2 | ||
41 | .global lcd_write_command_ex | ||
42 | .type lcd_write_command_ex,@function | ||
43 | |||
44 | lcd_write_command_ex: | ||
45 | lea.l 0xf0000000, %a0 | ||
46 | |||
47 | move.l (4, %sp), %d0 /* Command */ | ||
48 | move.w %d0, (%a0)+ /* Write to LCD, set A0 = 1 */ | ||
49 | |||
50 | move.l (8, %sp), %d0 /* Data */ | ||
51 | cmp.l #-1, %d0 /* -1? */ | ||
52 | beq.b .last | ||
53 | move.w %d0, (%a0) /* Write to LCD */ | ||
54 | |||
55 | move.l (12, %sp), %d0 /* Data */ | ||
56 | cmp.l #-1, %d0 /* -1? */ | ||
57 | beq.b .last | ||
58 | move.w %d0, (%a0) /* Write to LCD */ | ||
59 | |||
60 | .last: | ||
61 | rts | ||
62 | .wcex_end: | ||
63 | .size lcd_write_command_ex,.wcex_end-lcd_write_command_ex | ||
64 | |||
65 | |||
66 | .align 2 | ||
67 | .global lcd_write_data | ||
68 | .type lcd_write_data,@function | ||
69 | |||
70 | lcd_write_data: | ||
71 | movem.l (4, %sp), %a0-%a1 /* Data pointer */ | ||
72 | move.l %a1, %d0 /* Length */ | ||
73 | lea 0xf0000002, %a1 | ||
74 | |||
75 | .loop: | ||
76 | /* When running in IRAM, this loop takes 10 cycles plus the LCD write. | ||
77 | The 10 cycles are necessary to follow the LCD timing specs | ||
78 | at 140MHz */ | ||
79 | nop /* 3(0/0) */ | ||
80 | move.b (%a0)+, %d1 /* 3(1/0) */ | ||
81 | move.w %d1, (%a1) /* 1(0/1) */ | ||
82 | subq.l #1, %d0 /* 1(0/0) */ | ||
83 | bne .loop /* 2(0/0) */ | ||
84 | rts | ||
85 | .wd_end: | ||
86 | .size lcd_write_data,.wd_end-lcd_write_data | ||
87 | |||
88 | |||
89 | .align 2 | ||
90 | .global lcd_grey_data | ||
91 | .type lcd_grey_data,@function | ||
92 | |||
93 | /* The main loop assumes the buffers are in SDRAM. Otherwise the LCD | ||
94 | * controller timing won't be met at 124 MHz and graphical glitches | ||
95 | * will occur. */ | ||
96 | |||
97 | lcd_grey_data: | ||
98 | lea.l (-11*4, %sp), %sp | ||
99 | movem.l %d2-%d7/%a2-%a6, (%sp) /* free some registers */ | ||
100 | movem.l (11*4+4, %sp), %a0-%a2 /* values, phases, length */ | ||
101 | lea.l (%a1, %a2.l*4), %a2 /* end address */ | ||
102 | lea 0xf0000002, %a3 /* LCD data port */ | ||
103 | moveq.l #24, %d6 /* shift count */ | ||
104 | move.l #0xc30c3, %d7 /* bit shuffle factor */ | ||
105 | |||
106 | moveq.l #12, %d2 | ||
107 | add.l %a1, %d2 | ||
108 | and.l #0xfffffff0, %d2 /* first line bound */ | ||
109 | cmp.l %d2, %a2 /* end address lower than first line bound? */ | ||
110 | bhs.s 1f | ||
111 | move.l %a2, %d2 /* -> adjust end address of head loop */ | ||
112 | 1: | ||
113 | cmp.l %a1, %d2 | ||
114 | bls.s .g_hend | ||
115 | |||
116 | .g_hloop: | ||
117 | move.l (%a1), %d0 /* fetch 4 pixel phases */ | ||
118 | |||
119 | move.l %d0, %d1 | ||
120 | and.l #0x80808080, %d1 /* separate MSBs of the 4 phases */ | ||
121 | eor.l %d1, %d0 /* clear them in %d0 */ | ||
122 | add.l (%a0)+, %d0 /* add 4 pixel values to the phases */ | ||
123 | move.l %d0, (%a1)+ /* store new phases, advance pointer */ | ||
124 | |||
125 | lsr.l #1, %d1 /* %d1 = .0.......1.......2.......3...... */ | ||
126 | mulu.l %d7, %d1 /* %d1 = 00112233112233..2233....33...... */ | ||
127 | not.l %d1 /* negate bits */ | ||
128 | lsr.l %d6, %d1 /* %d1 = ........................00112233 */ | ||
129 | move.w %d1, (%a3) /* write pixel block */ | ||
130 | |||
131 | cmp.l %a1, %d2 /* go up to first line bound */ | ||
132 | bhi.s .g_hloop | ||
133 | |||
134 | .g_hend: | ||
135 | cmp.l %a1, %a2 | ||
136 | bls.w .g_tend | ||
137 | lea.l (-12, %a2), %a2 | ||
138 | cmp.l %a1, %a2 | ||
139 | bls.s .g_lend | ||
140 | |||
141 | .g_lloop: | ||
142 | movem.l (%a1), %d0-%d3 /* fetch 4 blocks of 4 pixel phases each */ | ||
143 | |||
144 | move.l %d0, %d4 /* calculate first pixel block */ | ||
145 | and.l #0x80808080, %d4 | ||
146 | eor.l %d4, %d0 | ||
147 | lsr.l #1, %d4 | ||
148 | mulu.l %d7, %d4 | ||
149 | not.l %d4 | ||
150 | lsr.l %d6, %d4 | ||
151 | |||
152 | move.w %d4, (%a3) /* write first pixel block to LCD */ | ||
153 | |||
154 | move.l %d1, %d5 /* calculate second pixel block */ | ||
155 | and.l #0x80808080, %d5 | ||
156 | eor.l %d5, %d1 | ||
157 | lsr.l #1, %d5 | ||
158 | mulu.l %d7, %d5 | ||
159 | not.l %d5 | ||
160 | lsr.l %d6, %d5 | ||
161 | |||
162 | move.l %d2, %d4 /* calculate third pixel block */ | ||
163 | and.l #0x80808080, %d4 | ||
164 | eor.l %d4, %d2 | ||
165 | lsr.l #1, %d4 | ||
166 | mulu.l %d7, %d4 | ||
167 | not.l %d4 | ||
168 | lsr.l %d6, %d4 | ||
169 | |||
170 | move.w %d5, (%a3) /* write second pixel block to LCD */ | ||
171 | |||
172 | movem.l (%a0), %d5/%a4-%a6 /* fetch 4 blocks of 4 pixel values each */ | ||
173 | lea.l (16, %a0), %a0 | ||
174 | |||
175 | move.w %d4, (%a3) /* write third pixel block to LCD */ | ||
176 | |||
177 | move.l %d3, %d4 /* calculate fourth pixel block */ | ||
178 | and.l #0x80808080, %d4 | ||
179 | eor.l %d4, %d3 | ||
180 | lsr.l #1, %d4 | ||
181 | mulu.l %d7, %d4 | ||
182 | not.l %d4 | ||
183 | lsr.l %d6, %d4 | ||
184 | |||
185 | add.l %d5, %d0 /* calculate 4*4 new pixel phases */ | ||
186 | add.l %a4, %d1 /* (packed addition) */ | ||
187 | add.l %a5, %d2 | ||
188 | add.l %a6, %d3 | ||
189 | |||
190 | movem.l %d0-%d3, (%a1) /* store 4*4 new pixel phases */ | ||
191 | lea.l (16, %a1), %a1 | ||
192 | |||
193 | move.w %d4, (%a3) /* write fourth pixel block to LCD */ | ||
194 | |||
195 | cmp.l %a1, %a2 /* go up to last line bound */ | ||
196 | bhi.s .g_lloop | ||
197 | |||
198 | .g_lend: | ||
199 | lea.l (12, %a2), %a2 | ||
200 | cmp.l %a1, %a2 | ||
201 | bls.s .g_tend | ||
202 | |||
203 | .g_tloop: | ||
204 | move.l (%a1), %d0 /* fetch 4 pixel phases */ | ||
205 | |||
206 | move.l %d0, %d1 | ||
207 | and.l #0x80808080, %d1 | ||
208 | eor.l %d1, %d0 | ||
209 | add.l (%a0)+, %d0 /* add 4 pixel values to the phases */ | ||
210 | move.l %d0, (%a1)+ /* store new phases, advance pointer */ | ||
211 | |||
212 | lsr.l #1, %d1 | ||
213 | mulu.l %d7, %d1 | ||
214 | not.l %d1 | ||
215 | lsr.l %d6, %d1 | ||
216 | move.w %d1, (%a3) /* write pixel block */ | ||
217 | |||
218 | cmp.l %a1, %a2 /* go up to end address */ | ||
219 | bhi.s .g_tloop | ||
220 | |||
221 | .g_tend: | ||
222 | movem.l (%sp), %d2-%d7/%a2-%a6 /* restore registers */ | ||
223 | lea.l (11*4, %sp), %sp | ||
224 | rts | ||
225 | |||
226 | .gd_end: | ||
227 | .size lcd_grey_data,.gd_end-lcd_grey_data | ||