qemu/hw/display/pl110_template.h
<<
>>
Prefs
   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#ifdef HOST_WORDS_BIGENDIAN
  19#define SWAP_WORDS 1
  20#endif
  21#elif ORDER == 1
  22#define NAME glue(bbbp_, BORDER)
  23#ifndef HOST_WORDS_BIGENDIAN
  24#define SWAP_WORDS 1
  25#endif
  26#else
  27#define SWAP_PIXELS 1
  28#define NAME glue(lbbp_, BORDER)
  29#ifdef HOST_WORDS_BIGENDIAN
  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
  38static 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
  66static 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
  94static 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
 122static 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
 146static 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
 192static 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
 222static 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
 260static 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