]> git.proxmox.com Git - mirror_qemu.git/blame - hw/display/pl110_template.h
i386: Add x-force-features option for testing
[mirror_qemu.git] / hw / display / pl110_template.h
CommitLineData
5fafdf24 1/*
bdd5003a
PB
2 * Arm PrimeCell PL110 Color LCD Controller
3 *
4 * Copyright (c) 2005 CodeSourcery, LLC.
5 * Written by Paul Brook
6 *
8e31bf38 7 * This code is licensed under the GNU LGPL
bdd5003a
PB
8 *
9 * Framebuffer format conversion routines.
10 */
11
12#ifndef ORDER
13
14#if BITS == 8
15#define COPY_PIXEL(to, from) *(to++) = from
16#elif BITS == 15 || BITS == 16
2cdaca90 17#define COPY_PIXEL(to, from) do { *(uint16_t *)to = from; to += 2; } while (0)
5fafdf24 18#elif BITS == 24
2cdaca90
PB
19#define COPY_PIXEL(to, from) \
20 do { \
21 *(to++) = from; \
22 *(to++) = (from) >> 8; \
23 *(to++) = (from) >> 16; \
24 } while (0)
bdd5003a 25#elif BITS == 32
2cdaca90 26#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
bdd5003a
PB
27#else
28#error unknown bit depth
29#endif
30
e9c05b42
AZ
31#undef RGB
32#define BORDER bgr
bdd5003a 33#define ORDER 0
47b43a1f 34#include "pl110_template.h"
bdd5003a 35#define ORDER 1
47b43a1f 36#include "pl110_template.h"
bdd5003a 37#define ORDER 2
47b43a1f 38#include "pl110_template.h"
e9c05b42
AZ
39#undef BORDER
40#define RGB
41#define BORDER rgb
42#define ORDER 0
47b43a1f 43#include "pl110_template.h"
e9c05b42 44#define ORDER 1
47b43a1f 45#include "pl110_template.h"
e9c05b42 46#define ORDER 2
47b43a1f 47#include "pl110_template.h"
e9c05b42 48#undef BORDER
bdd5003a 49
4fbf5556 50static drawfn glue(pl110_draw_fn_,BITS)[48] =
bdd5003a 51{
e9c05b42
AZ
52 glue(pl110_draw_line1_lblp_bgr,BITS),
53 glue(pl110_draw_line2_lblp_bgr,BITS),
54 glue(pl110_draw_line4_lblp_bgr,BITS),
55 glue(pl110_draw_line8_lblp_bgr,BITS),
4fbf5556 56 glue(pl110_draw_line16_555_lblp_bgr,BITS),
e9c05b42 57 glue(pl110_draw_line32_lblp_bgr,BITS),
4fbf5556
PM
58 glue(pl110_draw_line16_lblp_bgr,BITS),
59 glue(pl110_draw_line12_lblp_bgr,BITS),
e9c05b42
AZ
60
61 glue(pl110_draw_line1_bbbp_bgr,BITS),
62 glue(pl110_draw_line2_bbbp_bgr,BITS),
63 glue(pl110_draw_line4_bbbp_bgr,BITS),
64 glue(pl110_draw_line8_bbbp_bgr,BITS),
4fbf5556 65 glue(pl110_draw_line16_555_bbbp_bgr,BITS),
e9c05b42 66 glue(pl110_draw_line32_bbbp_bgr,BITS),
4fbf5556
PM
67 glue(pl110_draw_line16_bbbp_bgr,BITS),
68 glue(pl110_draw_line12_bbbp_bgr,BITS),
e9c05b42
AZ
69
70 glue(pl110_draw_line1_lbbp_bgr,BITS),
71 glue(pl110_draw_line2_lbbp_bgr,BITS),
72 glue(pl110_draw_line4_lbbp_bgr,BITS),
73 glue(pl110_draw_line8_lbbp_bgr,BITS),
4fbf5556 74 glue(pl110_draw_line16_555_lbbp_bgr,BITS),
e9c05b42 75 glue(pl110_draw_line32_lbbp_bgr,BITS),
4fbf5556
PM
76 glue(pl110_draw_line16_lbbp_bgr,BITS),
77 glue(pl110_draw_line12_lbbp_bgr,BITS),
e9c05b42
AZ
78
79 glue(pl110_draw_line1_lblp_rgb,BITS),
80 glue(pl110_draw_line2_lblp_rgb,BITS),
81 glue(pl110_draw_line4_lblp_rgb,BITS),
82 glue(pl110_draw_line8_lblp_rgb,BITS),
4fbf5556 83 glue(pl110_draw_line16_555_lblp_rgb,BITS),
e9c05b42 84 glue(pl110_draw_line32_lblp_rgb,BITS),
4fbf5556
PM
85 glue(pl110_draw_line16_lblp_rgb,BITS),
86 glue(pl110_draw_line12_lblp_rgb,BITS),
e9c05b42
AZ
87
88 glue(pl110_draw_line1_bbbp_rgb,BITS),
89 glue(pl110_draw_line2_bbbp_rgb,BITS),
90 glue(pl110_draw_line4_bbbp_rgb,BITS),
91 glue(pl110_draw_line8_bbbp_rgb,BITS),
4fbf5556 92 glue(pl110_draw_line16_555_bbbp_rgb,BITS),
e9c05b42 93 glue(pl110_draw_line32_bbbp_rgb,BITS),
4fbf5556
PM
94 glue(pl110_draw_line16_bbbp_rgb,BITS),
95 glue(pl110_draw_line12_bbbp_rgb,BITS),
e9c05b42
AZ
96
97 glue(pl110_draw_line1_lbbp_rgb,BITS),
98 glue(pl110_draw_line2_lbbp_rgb,BITS),
99 glue(pl110_draw_line4_lbbp_rgb,BITS),
100 glue(pl110_draw_line8_lbbp_rgb,BITS),
4fbf5556 101 glue(pl110_draw_line16_555_lbbp_rgb,BITS),
e9c05b42 102 glue(pl110_draw_line32_lbbp_rgb,BITS),
4fbf5556
PM
103 glue(pl110_draw_line16_lbbp_rgb,BITS),
104 glue(pl110_draw_line12_lbbp_rgb,BITS),
bdd5003a
PB
105};
106
107#undef BITS
108#undef COPY_PIXEL
109
110#else
111
112#if ORDER == 0
e9c05b42 113#define NAME glue(glue(lblp_, BORDER), BITS)
e2542fe2 114#ifdef HOST_WORDS_BIGENDIAN
bdd5003a
PB
115#define SWAP_WORDS 1
116#endif
117#elif ORDER == 1
e9c05b42 118#define NAME glue(glue(bbbp_, BORDER), BITS)
e2542fe2 119#ifndef HOST_WORDS_BIGENDIAN
bdd5003a
PB
120#define SWAP_WORDS 1
121#endif
122#else
123#define SWAP_PIXELS 1
e9c05b42 124#define NAME glue(glue(lbbp_, BORDER), BITS)
e2542fe2 125#ifdef HOST_WORDS_BIGENDIAN
bdd5003a
PB
126#define SWAP_WORDS 1
127#endif
128#endif
129
130#define FN_2(x, y) FN(x, y) FN(x+1, y)
1f9519c9 131#define FN_4(x, y) FN_2(x, y) FN_2(x+2, y)
bdd5003a
PB
132#define FN_8(y) FN_4(0, y) FN_4(4, y)
133
714fa308 134static void glue(pl110_draw_line1_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
bdd5003a 135{
6e4c0d1f 136 uint32_t *palette = opaque;
bdd5003a
PB
137 uint32_t data;
138 while (width > 0) {
139 data = *(uint32_t *)src;
140#ifdef SWAP_PIXELS
6e4c0d1f 141#define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 7 - (x))) & 1]);
bdd5003a 142#else
6e4c0d1f 143#define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x) + y)) & 1]);
bdd5003a 144#endif
be9d3657 145#ifdef SWAP_WORDS
bdd5003a
PB
146 FN_8(24)
147 FN_8(16)
148 FN_8(8)
149 FN_8(0)
150#else
151 FN_8(0)
152 FN_8(8)
153 FN_8(16)
154 FN_8(24)
155#endif
156#undef FN
157 width -= 32;
158 src += 4;
159 }
160}
161
714fa308 162static void glue(pl110_draw_line2_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
bdd5003a 163{
6e4c0d1f 164 uint32_t *palette = opaque;
bdd5003a
PB
165 uint32_t data;
166 while (width > 0) {
167 data = *(uint32_t *)src;
168#ifdef SWAP_PIXELS
6e4c0d1f 169#define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 6 - (x)*2)) & 3]);
bdd5003a 170#else
6e4c0d1f 171#define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*2 + y)) & 3]);
bdd5003a 172#endif
be9d3657 173#ifdef SWAP_WORDS
bdd5003a
PB
174 FN_4(0, 24)
175 FN_4(0, 16)
176 FN_4(0, 8)
177 FN_4(0, 0)
178#else
179 FN_4(0, 0)
180 FN_4(0, 8)
181 FN_4(0, 16)
182 FN_4(0, 24)
183#endif
184#undef FN
185 width -= 16;
186 src += 4;
187 }
188}
189
714fa308 190static void glue(pl110_draw_line4_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
bdd5003a 191{
6e4c0d1f 192 uint32_t *palette = opaque;
bdd5003a
PB
193 uint32_t data;
194 while (width > 0) {
195 data = *(uint32_t *)src;
196#ifdef SWAP_PIXELS
6e4c0d1f 197#define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 4 - (x)*4)) & 0xf]);
bdd5003a 198#else
6e4c0d1f 199#define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*4 + y)) & 0xf]);
bdd5003a 200#endif
be9d3657 201#ifdef SWAP_WORDS
bdd5003a
PB
202 FN_2(0, 24)
203 FN_2(0, 16)
204 FN_2(0, 8)
205 FN_2(0, 0)
206#else
207 FN_2(0, 0)
208 FN_2(0, 8)
209 FN_2(0, 16)
210 FN_2(0, 24)
211#endif
212#undef FN
213 width -= 8;
214 src += 4;
215 }
216}
217
714fa308 218static void glue(pl110_draw_line8_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
bdd5003a 219{
6e4c0d1f 220 uint32_t *palette = opaque;
bdd5003a
PB
221 uint32_t data;
222 while (width > 0) {
223 data = *(uint32_t *)src;
6e4c0d1f 224#define FN(x) COPY_PIXEL(d, palette[(data >> (x)) & 0xff]);
be9d3657 225#ifdef SWAP_WORDS
bdd5003a
PB
226 FN(24)
227 FN(16)
228 FN(8)
229 FN(0)
230#else
231 FN(0)
232 FN(8)
233 FN(16)
234 FN(24)
235#endif
236#undef FN
237 width -= 4;
238 src += 4;
239 }
240}
241
714fa308 242static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
bdd5003a
PB
243{
244 uint32_t data;
245 unsigned int r, g, b;
246 while (width > 0) {
247 data = *(uint32_t *)src;
be9d3657 248#ifdef SWAP_WORDS
bdd5003a
PB
249 data = bswap32(data);
250#endif
e9c05b42
AZ
251#ifdef RGB
252#define LSB r
253#define MSB b
254#else
255#define LSB b
256#define MSB r
257#endif
bdd5003a 258#if 0
e9c05b42 259 LSB = data & 0x1f;
bdd5003a
PB
260 data >>= 5;
261 g = data & 0x3f;
262 data >>= 6;
e9c05b42 263 MSB = data & 0x1f;
bdd5003a
PB
264 data >>= 5;
265#else
e9c05b42 266 LSB = (data & 0x1f) << 3;
bdd5003a
PB
267 data >>= 5;
268 g = (data & 0x3f) << 2;
269 data >>= 6;
e9c05b42 270 MSB = (data & 0x1f) << 3;
bdd5003a
PB
271 data >>= 5;
272#endif
273 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
e9c05b42 274 LSB = (data & 0x1f) << 3;
bdd5003a
PB
275 data >>= 5;
276 g = (data & 0x3f) << 2;
277 data >>= 6;
e9c05b42 278 MSB = (data & 0x1f) << 3;
bdd5003a
PB
279 data >>= 5;
280 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
e9c05b42
AZ
281#undef MSB
282#undef LSB
bdd5003a
PB
283 width -= 2;
284 src += 4;
285 }
286}
287
714fa308 288static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
bdd5003a
PB
289{
290 uint32_t data;
291 unsigned int r, g, b;
292 while (width > 0) {
293 data = *(uint32_t *)src;
e9c05b42
AZ
294#ifdef RGB
295#define LSB r
296#define MSB b
297#else
298#define LSB b
299#define MSB r
300#endif
399a4e21 301#ifndef SWAP_WORDS
e9c05b42 302 LSB = data & 0xff;
bdd5003a 303 g = (data >> 8) & 0xff;
e9c05b42 304 MSB = (data >> 16) & 0xff;
bdd5003a 305#else
e9c05b42 306 LSB = (data >> 24) & 0xff;
bdd5003a 307 g = (data >> 16) & 0xff;
e9c05b42 308 MSB = (data >> 8) & 0xff;
bdd5003a
PB
309#endif
310 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
e9c05b42
AZ
311#undef MSB
312#undef LSB
bdd5003a
PB
313 width--;
314 src += 4;
315 }
316}
317
4fbf5556
PM
318static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
319{
320 /* RGB 555 plus an intensity bit (which we ignore) */
321 uint32_t data;
322 unsigned int r, g, b;
323 while (width > 0) {
324 data = *(uint32_t *)src;
325#ifdef SWAP_WORDS
326 data = bswap32(data);
327#endif
328#ifdef RGB
329#define LSB r
330#define MSB b
331#else
332#define LSB b
333#define MSB r
334#endif
335 LSB = (data & 0x1f) << 3;
336 data >>= 5;
337 g = (data & 0x1f) << 3;
338 data >>= 5;
339 MSB = (data & 0x1f) << 3;
340 data >>= 5;
341 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
342 LSB = (data & 0x1f) << 3;
343 data >>= 5;
344 g = (data & 0x1f) << 3;
345 data >>= 5;
346 MSB = (data & 0x1f) << 3;
347 data >>= 6;
348 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
349#undef MSB
350#undef LSB
351 width -= 2;
352 src += 4;
353 }
354}
355
356static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
357{
358 /* RGB 444 with 4 bits of zeroes at the top of each halfword */
359 uint32_t data;
360 unsigned int r, g, b;
361 while (width > 0) {
362 data = *(uint32_t *)src;
363#ifdef SWAP_WORDS
364 data = bswap32(data);
365#endif
366#ifdef RGB
367#define LSB r
368#define MSB b
369#else
370#define LSB b
371#define MSB r
372#endif
373 LSB = (data & 0xf) << 4;
374 data >>= 4;
375 g = (data & 0xf) << 4;
376 data >>= 4;
377 MSB = (data & 0xf) << 4;
378 data >>= 8;
379 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
380 LSB = (data & 0xf) << 4;
381 data >>= 4;
382 g = (data & 0xf) << 4;
383 data >>= 4;
384 MSB = (data & 0xf) << 4;
385 data >>= 8;
386 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
387#undef MSB
388#undef LSB
389 width -= 2;
390 src += 4;
391 }
392}
393
bdd5003a
PB
394#undef SWAP_PIXELS
395#undef NAME
396#undef SWAP_WORDS
397#undef ORDER
398
399#endif