target/arm: Implement AArch32 HCR and HCR2
[qemu.git] / hw / display / pl110_template.h
blob36ba791c6fdf65520e8407ab01395adaf2015700
1 /*
2 * Arm PrimeCell PL110 Color LCD Controller
4 * Copyright (c) 2005 CodeSourcery, LLC.
5 * Written by Paul Brook
7 * This code is licensed under the GNU LGPL
9 * Framebuffer format conversion routines.
12 #ifndef ORDER
14 #if BITS == 8
15 #define COPY_PIXEL(to, from) *(to++) = from
16 #elif BITS == 15 || BITS == 16
17 #define COPY_PIXEL(to, from) do { *(uint16_t *)to = from; to += 2; } while (0)
18 #elif BITS == 24
19 #define COPY_PIXEL(to, from) \
20 do { \
21 *(to++) = from; \
22 *(to++) = (from) >> 8; \
23 *(to++) = (from) >> 16; \
24 } while (0)
25 #elif BITS == 32
26 #define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
27 #else
28 #error unknown bit depth
29 #endif
31 #undef RGB
32 #define BORDER bgr
33 #define ORDER 0
34 #include "pl110_template.h"
35 #define ORDER 1
36 #include "pl110_template.h"
37 #define ORDER 2
38 #include "pl110_template.h"
39 #undef BORDER
40 #define RGB
41 #define BORDER rgb
42 #define ORDER 0
43 #include "pl110_template.h"
44 #define ORDER 1
45 #include "pl110_template.h"
46 #define ORDER 2
47 #include "pl110_template.h"
48 #undef BORDER
50 static drawfn glue(pl110_draw_fn_,BITS)[48] =
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),
56 glue(pl110_draw_line16_555_lblp_bgr,BITS),
57 glue(pl110_draw_line32_lblp_bgr,BITS),
58 glue(pl110_draw_line16_lblp_bgr,BITS),
59 glue(pl110_draw_line12_lblp_bgr,BITS),
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),
65 glue(pl110_draw_line16_555_bbbp_bgr,BITS),
66 glue(pl110_draw_line32_bbbp_bgr,BITS),
67 glue(pl110_draw_line16_bbbp_bgr,BITS),
68 glue(pl110_draw_line12_bbbp_bgr,BITS),
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),
74 glue(pl110_draw_line16_555_lbbp_bgr,BITS),
75 glue(pl110_draw_line32_lbbp_bgr,BITS),
76 glue(pl110_draw_line16_lbbp_bgr,BITS),
77 glue(pl110_draw_line12_lbbp_bgr,BITS),
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),
83 glue(pl110_draw_line16_555_lblp_rgb,BITS),
84 glue(pl110_draw_line32_lblp_rgb,BITS),
85 glue(pl110_draw_line16_lblp_rgb,BITS),
86 glue(pl110_draw_line12_lblp_rgb,BITS),
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),
92 glue(pl110_draw_line16_555_bbbp_rgb,BITS),
93 glue(pl110_draw_line32_bbbp_rgb,BITS),
94 glue(pl110_draw_line16_bbbp_rgb,BITS),
95 glue(pl110_draw_line12_bbbp_rgb,BITS),
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),
101 glue(pl110_draw_line16_555_lbbp_rgb,BITS),
102 glue(pl110_draw_line32_lbbp_rgb,BITS),
103 glue(pl110_draw_line16_lbbp_rgb,BITS),
104 glue(pl110_draw_line12_lbbp_rgb,BITS),
107 #undef BITS
108 #undef COPY_PIXEL
110 #else
112 #if ORDER == 0
113 #define NAME glue(glue(lblp_, BORDER), BITS)
114 #ifdef HOST_WORDS_BIGENDIAN
115 #define SWAP_WORDS 1
116 #endif
117 #elif ORDER == 1
118 #define NAME glue(glue(bbbp_, BORDER), BITS)
119 #ifndef HOST_WORDS_BIGENDIAN
120 #define SWAP_WORDS 1
121 #endif
122 #else
123 #define SWAP_PIXELS 1
124 #define NAME glue(glue(lbbp_, BORDER), BITS)
125 #ifdef HOST_WORDS_BIGENDIAN
126 #define SWAP_WORDS 1
127 #endif
128 #endif
130 #define FN_2(x, y) FN(x, y) FN(x+1, y)
131 #define FN_4(x, y) FN_2(x, y) FN_2(x+2, y)
132 #define FN_8(y) FN_4(0, y) FN_4(4, y)
134 static void glue(pl110_draw_line1_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
136 uint32_t *palette = opaque;
137 uint32_t data;
138 while (width > 0) {
139 data = *(uint32_t *)src;
140 #ifdef SWAP_PIXELS
141 #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 7 - (x))) & 1]);
142 #else
143 #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x) + y)) & 1]);
144 #endif
145 #ifdef SWAP_WORDS
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;
162 static void glue(pl110_draw_line2_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
164 uint32_t *palette = opaque;
165 uint32_t data;
166 while (width > 0) {
167 data = *(uint32_t *)src;
168 #ifdef SWAP_PIXELS
169 #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 6 - (x)*2)) & 3]);
170 #else
171 #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*2 + y)) & 3]);
172 #endif
173 #ifdef SWAP_WORDS
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;
190 static void glue(pl110_draw_line4_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
192 uint32_t *palette = opaque;
193 uint32_t data;
194 while (width > 0) {
195 data = *(uint32_t *)src;
196 #ifdef SWAP_PIXELS
197 #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 4 - (x)*4)) & 0xf]);
198 #else
199 #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*4 + y)) & 0xf]);
200 #endif
201 #ifdef SWAP_WORDS
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;
218 static void glue(pl110_draw_line8_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
220 uint32_t *palette = opaque;
221 uint32_t data;
222 while (width > 0) {
223 data = *(uint32_t *)src;
224 #define FN(x) COPY_PIXEL(d, palette[(data >> (x)) & 0xff]);
225 #ifdef SWAP_WORDS
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;
242 static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
244 uint32_t data;
245 unsigned int r, g, b;
246 while (width > 0) {
247 data = *(uint32_t *)src;
248 #ifdef SWAP_WORDS
249 data = bswap32(data);
250 #endif
251 #ifdef RGB
252 #define LSB r
253 #define MSB b
254 #else
255 #define LSB b
256 #define MSB r
257 #endif
258 #if 0
259 LSB = data & 0x1f;
260 data >>= 5;
261 g = data & 0x3f;
262 data >>= 6;
263 MSB = data & 0x1f;
264 data >>= 5;
265 #else
266 LSB = (data & 0x1f) << 3;
267 data >>= 5;
268 g = (data & 0x3f) << 2;
269 data >>= 6;
270 MSB = (data & 0x1f) << 3;
271 data >>= 5;
272 #endif
273 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
274 LSB = (data & 0x1f) << 3;
275 data >>= 5;
276 g = (data & 0x3f) << 2;
277 data >>= 6;
278 MSB = (data & 0x1f) << 3;
279 data >>= 5;
280 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
281 #undef MSB
282 #undef LSB
283 width -= 2;
284 src += 4;
288 static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
290 uint32_t data;
291 unsigned int r, g, b;
292 while (width > 0) {
293 data = *(uint32_t *)src;
294 #ifdef RGB
295 #define LSB r
296 #define MSB b
297 #else
298 #define LSB b
299 #define MSB r
300 #endif
301 #ifndef SWAP_WORDS
302 LSB = data & 0xff;
303 g = (data >> 8) & 0xff;
304 MSB = (data >> 16) & 0xff;
305 #else
306 LSB = (data >> 24) & 0xff;
307 g = (data >> 16) & 0xff;
308 MSB = (data >> 8) & 0xff;
309 #endif
310 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
311 #undef MSB
312 #undef LSB
313 width--;
314 src += 4;
318 static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
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;
356 static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
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;
394 #undef SWAP_PIXELS
395 #undef NAME
396 #undef SWAP_WORDS
397 #undef ORDER
399 #endif