xref: /qemu/hw/display/pl110_template.h (revision 1be5a765c08cee3a9587c8a8d3fc2ea247b13f9c)
1bdd5003aSpbrook /*
2bdd5003aSpbrook  * Arm PrimeCell PL110 Color LCD Controller
3bdd5003aSpbrook  *
4bdd5003aSpbrook  * Copyright (c) 2005 CodeSourcery, LLC.
5bdd5003aSpbrook  * Written by Paul Brook
6bdd5003aSpbrook  *
78e31bf38SMatthew Fernandez  * This code is licensed under the GNU LGPL
8bdd5003aSpbrook  *
9bdd5003aSpbrook  * Framebuffer format conversion routines.
10bdd5003aSpbrook  */
11bdd5003aSpbrook 
12bdd5003aSpbrook #ifndef ORDER
13560ebce6SPeter Maydell #error "pl110_template.h is only for inclusion by pl110.c"
14bdd5003aSpbrook #endif
15bdd5003aSpbrook 
16bdd5003aSpbrook #if ORDER == 0
17ba1c16e4SPeter Maydell #define NAME glue(lblp_, BORDER)
18*e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
19bdd5003aSpbrook #define SWAP_WORDS 1
20bdd5003aSpbrook #endif
21bdd5003aSpbrook #elif ORDER == 1
22ba1c16e4SPeter Maydell #define NAME glue(bbbp_, BORDER)
23*e03b5686SMarc-André Lureau #if !HOST_BIG_ENDIAN
24bdd5003aSpbrook #define SWAP_WORDS 1
25bdd5003aSpbrook #endif
26bdd5003aSpbrook #else
27bdd5003aSpbrook #define SWAP_PIXELS 1
28ba1c16e4SPeter Maydell #define NAME glue(lbbp_, BORDER)
29*e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
30bdd5003aSpbrook #define SWAP_WORDS 1
31bdd5003aSpbrook #endif
32bdd5003aSpbrook #endif
33bdd5003aSpbrook 
34bdd5003aSpbrook #define FN_2(x, y) FN(x, y) FN(x+1, y)
351f9519c9Spbrook #define FN_4(x, y) FN_2(x, y) FN_2(x+2, y)
36bdd5003aSpbrook #define FN_8(y) FN_4(0, y) FN_4(4, y)
37bdd5003aSpbrook 
glue(pl110_draw_line1_,NAME)38714fa308Spbrook static void glue(pl110_draw_line1_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
39bdd5003aSpbrook {
406e4c0d1fSPeter Maydell     uint32_t *palette = opaque;
41bdd5003aSpbrook     uint32_t data;
42bdd5003aSpbrook     while (width > 0) {
43bdd5003aSpbrook         data = *(uint32_t *)src;
44bdd5003aSpbrook #ifdef SWAP_PIXELS
456e4c0d1fSPeter Maydell #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 7 - (x))) & 1]);
46bdd5003aSpbrook #else
476e4c0d1fSPeter Maydell #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x) + y)) & 1]);
48bdd5003aSpbrook #endif
49be9d3657Spbrook #ifdef SWAP_WORDS
50bdd5003aSpbrook         FN_8(24)
51bdd5003aSpbrook         FN_8(16)
52bdd5003aSpbrook         FN_8(8)
53bdd5003aSpbrook         FN_8(0)
54bdd5003aSpbrook #else
55bdd5003aSpbrook         FN_8(0)
56bdd5003aSpbrook         FN_8(8)
57bdd5003aSpbrook         FN_8(16)
58bdd5003aSpbrook         FN_8(24)
59bdd5003aSpbrook #endif
60bdd5003aSpbrook #undef FN
61bdd5003aSpbrook         width -= 32;
62bdd5003aSpbrook         src += 4;
63bdd5003aSpbrook     }
64bdd5003aSpbrook }
65bdd5003aSpbrook 
glue(pl110_draw_line2_,NAME)66714fa308Spbrook static void glue(pl110_draw_line2_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
67bdd5003aSpbrook {
686e4c0d1fSPeter Maydell     uint32_t *palette = opaque;
69bdd5003aSpbrook     uint32_t data;
70bdd5003aSpbrook     while (width > 0) {
71bdd5003aSpbrook         data = *(uint32_t *)src;
72bdd5003aSpbrook #ifdef SWAP_PIXELS
736e4c0d1fSPeter Maydell #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 6 - (x)*2)) & 3]);
74bdd5003aSpbrook #else
756e4c0d1fSPeter Maydell #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*2 + y)) & 3]);
76bdd5003aSpbrook #endif
77be9d3657Spbrook #ifdef SWAP_WORDS
78bdd5003aSpbrook         FN_4(0, 24)
79bdd5003aSpbrook         FN_4(0, 16)
80bdd5003aSpbrook         FN_4(0, 8)
81bdd5003aSpbrook         FN_4(0, 0)
82bdd5003aSpbrook #else
83bdd5003aSpbrook         FN_4(0, 0)
84bdd5003aSpbrook         FN_4(0, 8)
85bdd5003aSpbrook         FN_4(0, 16)
86bdd5003aSpbrook         FN_4(0, 24)
87bdd5003aSpbrook #endif
88bdd5003aSpbrook #undef FN
89bdd5003aSpbrook         width -= 16;
90bdd5003aSpbrook         src += 4;
91bdd5003aSpbrook     }
92bdd5003aSpbrook }
93bdd5003aSpbrook 
glue(pl110_draw_line4_,NAME)94714fa308Spbrook static void glue(pl110_draw_line4_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
95bdd5003aSpbrook {
966e4c0d1fSPeter Maydell     uint32_t *palette = opaque;
97bdd5003aSpbrook     uint32_t data;
98bdd5003aSpbrook     while (width > 0) {
99bdd5003aSpbrook         data = *(uint32_t *)src;
100bdd5003aSpbrook #ifdef SWAP_PIXELS
1016e4c0d1fSPeter Maydell #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 4 - (x)*4)) & 0xf]);
102bdd5003aSpbrook #else
1036e4c0d1fSPeter Maydell #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*4 + y)) & 0xf]);
104bdd5003aSpbrook #endif
105be9d3657Spbrook #ifdef SWAP_WORDS
106bdd5003aSpbrook         FN_2(0, 24)
107bdd5003aSpbrook         FN_2(0, 16)
108bdd5003aSpbrook         FN_2(0, 8)
109bdd5003aSpbrook         FN_2(0, 0)
110bdd5003aSpbrook #else
111bdd5003aSpbrook         FN_2(0, 0)
112bdd5003aSpbrook         FN_2(0, 8)
113bdd5003aSpbrook         FN_2(0, 16)
114bdd5003aSpbrook         FN_2(0, 24)
115bdd5003aSpbrook #endif
116bdd5003aSpbrook #undef FN
117bdd5003aSpbrook         width -= 8;
118bdd5003aSpbrook         src += 4;
119bdd5003aSpbrook     }
120bdd5003aSpbrook }
121bdd5003aSpbrook 
glue(pl110_draw_line8_,NAME)122714fa308Spbrook static void glue(pl110_draw_line8_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
123bdd5003aSpbrook {
1246e4c0d1fSPeter Maydell     uint32_t *palette = opaque;
125bdd5003aSpbrook     uint32_t data;
126bdd5003aSpbrook     while (width > 0) {
127bdd5003aSpbrook         data = *(uint32_t *)src;
1286e4c0d1fSPeter Maydell #define FN(x) COPY_PIXEL(d, palette[(data >> (x)) & 0xff]);
129be9d3657Spbrook #ifdef SWAP_WORDS
130bdd5003aSpbrook         FN(24)
131bdd5003aSpbrook         FN(16)
132bdd5003aSpbrook         FN(8)
133bdd5003aSpbrook         FN(0)
134bdd5003aSpbrook #else
135bdd5003aSpbrook         FN(0)
136bdd5003aSpbrook         FN(8)
137bdd5003aSpbrook         FN(16)
138bdd5003aSpbrook         FN(24)
139bdd5003aSpbrook #endif
140bdd5003aSpbrook #undef FN
141bdd5003aSpbrook         width -= 4;
142bdd5003aSpbrook         src += 4;
143bdd5003aSpbrook     }
144bdd5003aSpbrook }
145bdd5003aSpbrook 
glue(pl110_draw_line16_,NAME)146714fa308Spbrook static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
147bdd5003aSpbrook {
148bdd5003aSpbrook     uint32_t data;
149bdd5003aSpbrook     unsigned int r, g, b;
150bdd5003aSpbrook     while (width > 0) {
151bdd5003aSpbrook         data = *(uint32_t *)src;
152be9d3657Spbrook #ifdef SWAP_WORDS
153bdd5003aSpbrook         data = bswap32(data);
154bdd5003aSpbrook #endif
155e9c05b42Sbalrog #ifdef RGB
156e9c05b42Sbalrog #define LSB r
157e9c05b42Sbalrog #define MSB b
158e9c05b42Sbalrog #else
159e9c05b42Sbalrog #define LSB b
160e9c05b42Sbalrog #define MSB r
161e9c05b42Sbalrog #endif
162bdd5003aSpbrook #if 0
163e9c05b42Sbalrog         LSB = data & 0x1f;
164bdd5003aSpbrook         data >>= 5;
165bdd5003aSpbrook         g = data & 0x3f;
166bdd5003aSpbrook         data >>= 6;
167e9c05b42Sbalrog         MSB = data & 0x1f;
168bdd5003aSpbrook         data >>= 5;
169bdd5003aSpbrook #else
170e9c05b42Sbalrog         LSB = (data & 0x1f) << 3;
171bdd5003aSpbrook         data >>= 5;
172bdd5003aSpbrook         g = (data & 0x3f) << 2;
173bdd5003aSpbrook         data >>= 6;
174e9c05b42Sbalrog         MSB = (data & 0x1f) << 3;
175bdd5003aSpbrook         data >>= 5;
176bdd5003aSpbrook #endif
177ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
178e9c05b42Sbalrog         LSB = (data & 0x1f) << 3;
179bdd5003aSpbrook         data >>= 5;
180bdd5003aSpbrook         g = (data & 0x3f) << 2;
181bdd5003aSpbrook         data >>= 6;
182e9c05b42Sbalrog         MSB = (data & 0x1f) << 3;
183bdd5003aSpbrook         data >>= 5;
184ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
185e9c05b42Sbalrog #undef MSB
186e9c05b42Sbalrog #undef LSB
187bdd5003aSpbrook         width -= 2;
188bdd5003aSpbrook         src += 4;
189bdd5003aSpbrook     }
190bdd5003aSpbrook }
191bdd5003aSpbrook 
glue(pl110_draw_line32_,NAME)192714fa308Spbrook static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
193bdd5003aSpbrook {
194bdd5003aSpbrook     uint32_t data;
195bdd5003aSpbrook     unsigned int r, g, b;
196bdd5003aSpbrook     while (width > 0) {
197bdd5003aSpbrook         data = *(uint32_t *)src;
198e9c05b42Sbalrog #ifdef RGB
199e9c05b42Sbalrog #define LSB r
200e9c05b42Sbalrog #define MSB b
201bdd5003aSpbrook #else
202e9c05b42Sbalrog #define LSB b
203e9c05b42Sbalrog #define MSB r
204e9c05b42Sbalrog #endif
205399a4e21SPaul Brook #ifndef SWAP_WORDS
206e9c05b42Sbalrog         LSB = data & 0xff;
207e9c05b42Sbalrog         g = (data >> 8) & 0xff;
208e9c05b42Sbalrog         MSB = (data >> 16) & 0xff;
209e9c05b42Sbalrog #else
210e9c05b42Sbalrog         LSB = (data >> 24) & 0xff;
211bdd5003aSpbrook         g = (data >> 16) & 0xff;
212e9c05b42Sbalrog         MSB = (data >> 8) & 0xff;
213bdd5003aSpbrook #endif
214ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
215e9c05b42Sbalrog #undef MSB
216e9c05b42Sbalrog #undef LSB
217bdd5003aSpbrook         width--;
218bdd5003aSpbrook         src += 4;
219bdd5003aSpbrook     }
220bdd5003aSpbrook }
221bdd5003aSpbrook 
glue(pl110_draw_line16_555_,NAME)2224fbf5556SPeter Maydell static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
2234fbf5556SPeter Maydell {
2244fbf5556SPeter Maydell     /* RGB 555 plus an intensity bit (which we ignore) */
2254fbf5556SPeter Maydell     uint32_t data;
2264fbf5556SPeter Maydell     unsigned int r, g, b;
2274fbf5556SPeter Maydell     while (width > 0) {
2284fbf5556SPeter Maydell         data = *(uint32_t *)src;
2294fbf5556SPeter Maydell #ifdef SWAP_WORDS
2304fbf5556SPeter Maydell         data = bswap32(data);
2314fbf5556SPeter Maydell #endif
2324fbf5556SPeter Maydell #ifdef RGB
2334fbf5556SPeter Maydell #define LSB r
2344fbf5556SPeter Maydell #define MSB b
2354fbf5556SPeter Maydell #else
2364fbf5556SPeter Maydell #define LSB b
2374fbf5556SPeter Maydell #define MSB r
2384fbf5556SPeter Maydell #endif
2394fbf5556SPeter Maydell         LSB = (data & 0x1f) << 3;
2404fbf5556SPeter Maydell         data >>= 5;
2414fbf5556SPeter Maydell         g = (data & 0x1f) << 3;
2424fbf5556SPeter Maydell         data >>= 5;
2434fbf5556SPeter Maydell         MSB = (data & 0x1f) << 3;
2444fbf5556SPeter Maydell         data >>= 5;
245ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
2464fbf5556SPeter Maydell         LSB = (data & 0x1f) << 3;
2474fbf5556SPeter Maydell         data >>= 5;
2484fbf5556SPeter Maydell         g = (data & 0x1f) << 3;
2494fbf5556SPeter Maydell         data >>= 5;
2504fbf5556SPeter Maydell         MSB = (data & 0x1f) << 3;
2514fbf5556SPeter Maydell         data >>= 6;
252ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
2534fbf5556SPeter Maydell #undef MSB
2544fbf5556SPeter Maydell #undef LSB
2554fbf5556SPeter Maydell         width -= 2;
2564fbf5556SPeter Maydell         src += 4;
2574fbf5556SPeter Maydell     }
2584fbf5556SPeter Maydell }
2594fbf5556SPeter Maydell 
glue(pl110_draw_line12_,NAME)2604fbf5556SPeter Maydell static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
2614fbf5556SPeter Maydell {
2624fbf5556SPeter Maydell     /* RGB 444 with 4 bits of zeroes at the top of each halfword */
2634fbf5556SPeter Maydell     uint32_t data;
2644fbf5556SPeter Maydell     unsigned int r, g, b;
2654fbf5556SPeter Maydell     while (width > 0) {
2664fbf5556SPeter Maydell         data = *(uint32_t *)src;
2674fbf5556SPeter Maydell #ifdef SWAP_WORDS
2684fbf5556SPeter Maydell         data = bswap32(data);
2694fbf5556SPeter Maydell #endif
2704fbf5556SPeter Maydell #ifdef RGB
2714fbf5556SPeter Maydell #define LSB r
2724fbf5556SPeter Maydell #define MSB b
2734fbf5556SPeter Maydell #else
2744fbf5556SPeter Maydell #define LSB b
2754fbf5556SPeter Maydell #define MSB r
2764fbf5556SPeter Maydell #endif
2774fbf5556SPeter Maydell         LSB = (data & 0xf) << 4;
2784fbf5556SPeter Maydell         data >>= 4;
2794fbf5556SPeter Maydell         g = (data & 0xf) << 4;
2804fbf5556SPeter Maydell         data >>= 4;
2814fbf5556SPeter Maydell         MSB = (data & 0xf) << 4;
2824fbf5556SPeter Maydell         data >>= 8;
283ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
2844fbf5556SPeter Maydell         LSB = (data & 0xf) << 4;
2854fbf5556SPeter Maydell         data >>= 4;
2864fbf5556SPeter Maydell         g = (data & 0xf) << 4;
2874fbf5556SPeter Maydell         data >>= 4;
2884fbf5556SPeter Maydell         MSB = (data & 0xf) << 4;
2894fbf5556SPeter Maydell         data >>= 8;
290ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
2914fbf5556SPeter Maydell #undef MSB
2924fbf5556SPeter Maydell #undef LSB
2934fbf5556SPeter Maydell         width -= 2;
2944fbf5556SPeter Maydell         src += 4;
2954fbf5556SPeter Maydell     }
2964fbf5556SPeter Maydell }
2974fbf5556SPeter Maydell 
298bdd5003aSpbrook #undef SWAP_PIXELS
299bdd5003aSpbrook #undef NAME
300bdd5003aSpbrook #undef SWAP_WORDS
301bdd5003aSpbrook #undef ORDER
302