xref: /qemu/hw/display/pl110_template.h (revision b2a3cbb8)
1 /*
2  * Arm PrimeCell PL110 Color LCD Controller
3  *
4  * Copyright (c) 2005 CodeSourcery, LLC.
5  * Written by Paul Brook
6  *
7  * This code is licensed under the GNU LGPL
8  *
9  * Framebuffer format conversion routines.
10  */
11 
12 #ifndef ORDER
13 #error "pl110_template.h is only for inclusion by pl110.c"
14 #endif
15 
16 #if ORDER == 0
17 #define NAME glue(lblp_, BORDER)
18 #if HOST_BIG_ENDIAN
19 #define SWAP_WORDS 1
20 #endif
21 #elif ORDER == 1
22 #define NAME glue(bbbp_, BORDER)
23 #if !HOST_BIG_ENDIAN
24 #define SWAP_WORDS 1
25 #endif
26 #else
27 #define SWAP_PIXELS 1
28 #define NAME glue(lbbp_, BORDER)
29 #if HOST_BIG_ENDIAN
30 #define SWAP_WORDS 1
31 #endif
32 #endif
33 
34 #define FN_2(x, y) FN(x, y) FN(x+1, y)
35 #define FN_4(x, y) FN_2(x, y) FN_2(x+2, y)
36 #define FN_8(y) FN_4(0, y) FN_4(4, y)
37 
38 static void glue(pl110_draw_line1_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
39 {
40     uint32_t *palette = opaque;
41     uint32_t data;
42     while (width > 0) {
43         data = *(uint32_t *)src;
44 #ifdef SWAP_PIXELS
45 #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 7 - (x))) & 1]);
46 #else
47 #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x) + y)) & 1]);
48 #endif
49 #ifdef SWAP_WORDS
50         FN_8(24)
51         FN_8(16)
52         FN_8(8)
53         FN_8(0)
54 #else
55         FN_8(0)
56         FN_8(8)
57         FN_8(16)
58         FN_8(24)
59 #endif
60 #undef FN
61         width -= 32;
62         src += 4;
63     }
64 }
65 
66 static void glue(pl110_draw_line2_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
67 {
68     uint32_t *palette = opaque;
69     uint32_t data;
70     while (width > 0) {
71         data = *(uint32_t *)src;
72 #ifdef SWAP_PIXELS
73 #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 6 - (x)*2)) & 3]);
74 #else
75 #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*2 + y)) & 3]);
76 #endif
77 #ifdef SWAP_WORDS
78         FN_4(0, 24)
79         FN_4(0, 16)
80         FN_4(0, 8)
81         FN_4(0, 0)
82 #else
83         FN_4(0, 0)
84         FN_4(0, 8)
85         FN_4(0, 16)
86         FN_4(0, 24)
87 #endif
88 #undef FN
89         width -= 16;
90         src += 4;
91     }
92 }
93 
94 static void glue(pl110_draw_line4_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
95 {
96     uint32_t *palette = opaque;
97     uint32_t data;
98     while (width > 0) {
99         data = *(uint32_t *)src;
100 #ifdef SWAP_PIXELS
101 #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 4 - (x)*4)) & 0xf]);
102 #else
103 #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*4 + y)) & 0xf]);
104 #endif
105 #ifdef SWAP_WORDS
106         FN_2(0, 24)
107         FN_2(0, 16)
108         FN_2(0, 8)
109         FN_2(0, 0)
110 #else
111         FN_2(0, 0)
112         FN_2(0, 8)
113         FN_2(0, 16)
114         FN_2(0, 24)
115 #endif
116 #undef FN
117         width -= 8;
118         src += 4;
119     }
120 }
121 
122 static void glue(pl110_draw_line8_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
123 {
124     uint32_t *palette = opaque;
125     uint32_t data;
126     while (width > 0) {
127         data = *(uint32_t *)src;
128 #define FN(x) COPY_PIXEL(d, palette[(data >> (x)) & 0xff]);
129 #ifdef SWAP_WORDS
130         FN(24)
131         FN(16)
132         FN(8)
133         FN(0)
134 #else
135         FN(0)
136         FN(8)
137         FN(16)
138         FN(24)
139 #endif
140 #undef FN
141         width -= 4;
142         src += 4;
143     }
144 }
145 
146 static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
147 {
148     uint32_t data;
149     unsigned int r, g, b;
150     while (width > 0) {
151         data = *(uint32_t *)src;
152 #ifdef SWAP_WORDS
153         data = bswap32(data);
154 #endif
155 #ifdef RGB
156 #define LSB r
157 #define MSB b
158 #else
159 #define LSB b
160 #define MSB r
161 #endif
162 #if 0
163         LSB = data & 0x1f;
164         data >>= 5;
165         g = data & 0x3f;
166         data >>= 6;
167         MSB = data & 0x1f;
168         data >>= 5;
169 #else
170         LSB = (data & 0x1f) << 3;
171         data >>= 5;
172         g = (data & 0x3f) << 2;
173         data >>= 6;
174         MSB = (data & 0x1f) << 3;
175         data >>= 5;
176 #endif
177         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
178         LSB = (data & 0x1f) << 3;
179         data >>= 5;
180         g = (data & 0x3f) << 2;
181         data >>= 6;
182         MSB = (data & 0x1f) << 3;
183         data >>= 5;
184         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
185 #undef MSB
186 #undef LSB
187         width -= 2;
188         src += 4;
189     }
190 }
191 
192 static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
193 {
194     uint32_t data;
195     unsigned int r, g, b;
196     while (width > 0) {
197         data = *(uint32_t *)src;
198 #ifdef RGB
199 #define LSB r
200 #define MSB b
201 #else
202 #define LSB b
203 #define MSB r
204 #endif
205 #ifndef SWAP_WORDS
206         LSB = data & 0xff;
207         g = (data >> 8) & 0xff;
208         MSB = (data >> 16) & 0xff;
209 #else
210         LSB = (data >> 24) & 0xff;
211         g = (data >> 16) & 0xff;
212         MSB = (data >> 8) & 0xff;
213 #endif
214         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
215 #undef MSB
216 #undef LSB
217         width--;
218         src += 4;
219     }
220 }
221 
222 static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
223 {
224     /* RGB 555 plus an intensity bit (which we ignore) */
225     uint32_t data;
226     unsigned int r, g, b;
227     while (width > 0) {
228         data = *(uint32_t *)src;
229 #ifdef SWAP_WORDS
230         data = bswap32(data);
231 #endif
232 #ifdef RGB
233 #define LSB r
234 #define MSB b
235 #else
236 #define LSB b
237 #define MSB r
238 #endif
239         LSB = (data & 0x1f) << 3;
240         data >>= 5;
241         g = (data & 0x1f) << 3;
242         data >>= 5;
243         MSB = (data & 0x1f) << 3;
244         data >>= 5;
245         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
246         LSB = (data & 0x1f) << 3;
247         data >>= 5;
248         g = (data & 0x1f) << 3;
249         data >>= 5;
250         MSB = (data & 0x1f) << 3;
251         data >>= 6;
252         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
253 #undef MSB
254 #undef LSB
255         width -= 2;
256         src += 4;
257     }
258 }
259 
260 static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
261 {
262     /* RGB 444 with 4 bits of zeroes at the top of each halfword */
263     uint32_t data;
264     unsigned int r, g, b;
265     while (width > 0) {
266         data = *(uint32_t *)src;
267 #ifdef SWAP_WORDS
268         data = bswap32(data);
269 #endif
270 #ifdef RGB
271 #define LSB r
272 #define MSB b
273 #else
274 #define LSB b
275 #define MSB r
276 #endif
277         LSB = (data & 0xf) << 4;
278         data >>= 4;
279         g = (data & 0xf) << 4;
280         data >>= 4;
281         MSB = (data & 0xf) << 4;
282         data >>= 8;
283         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
284         LSB = (data & 0xf) << 4;
285         data >>= 4;
286         g = (data & 0xf) << 4;
287         data >>= 4;
288         MSB = (data & 0xf) << 4;
289         data >>= 8;
290         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
291 #undef MSB
292 #undef LSB
293         width -= 2;
294         src += 4;
295     }
296 }
297 
298 #undef SWAP_PIXELS
299 #undef NAME
300 #undef SWAP_WORDS
301 #undef ORDER
302