Commit bdd5003ae58baf4fb3fde9862630b97b2c1f058c

Authored by pbrook
1 parent a41b2ff2

Arm display emulation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1746 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -339,7 +339,7 @@ VL_OBJS+= slavio_timer.o slavio_serial.o slavio_misc.o fdc.o esp.o
339 339 endif
340 340 endif
341 341 ifeq ($(TARGET_BASE_ARCH), arm)
342   -VL_OBJS+= integratorcp.o ps2.o smc91c111.o
  342 +VL_OBJS+= integratorcp.o ps2.o smc91c111.o pl110.o
343 343 endif
344 344 ifdef CONFIG_GDBSTUB
345 345 VL_OBJS+=gdbstub.o
... ... @@ -439,6 +439,7 @@ endif
439 439  
440 440 ifeq ($(TARGET_ARCH), arm)
441 441 op.o: op.c op_template.h
  442 +pl110.o: pl110_template.h
442 443 endif
443 444  
444 445 ifeq ($(TARGET_BASE_ARCH), sparc)
... ...
hw/integratorcp.c
... ... @@ -27,8 +27,11 @@ void irq_info(void)
27 27 {
28 28 }
29 29  
  30 +static void *lcd;
  31 +
30 32 void vga_update_display(void)
31 33 {
  34 + pl110_update_display(lcd);
32 35 }
33 36  
34 37 void vga_screen_dump(const char *filename)
... ... @@ -37,6 +40,7 @@ void vga_screen_dump(const char *filename)
37 40  
38 41 void vga_invalidate_display(void)
39 42 {
  43 + pl110_invalidate_display(lcd);
40 44 }
41 45  
42 46 void DMA_run (void)
... ... @@ -1204,6 +1208,7 @@ static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
1204 1208 exit (1);
1205 1209 }
1206 1210 }
  1211 + lcd = pl110_init(ds, 0xc0000000, pic, 22);
1207 1212  
1208 1213 /* Load the kernel. */
1209 1214 if (!kernel_filename) {
... ...
hw/pl110.c 0 → 100644
  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 licenced under the GNU LGPL
  8 + */
  9 +
  10 +#include "vl.h"
  11 +
  12 +#define PL110_CR_EN 0x001
  13 +#define PL110_CR_BEBO 0x200
  14 +#define PL110_CR_BEPO 0x400
  15 +#define PL110_CR_PWR 0x800
  16 +
  17 +enum pl110_bppmode
  18 +{
  19 + BPP_1,
  20 + BPP_2,
  21 + BPP_4,
  22 + BPP_8,
  23 + BPP_16,
  24 + BPP_32
  25 +};
  26 +
  27 +typedef struct {
  28 + uint32_t base;
  29 + DisplayState *ds;
  30 + void *pic;
  31 + uint32_t timing[4];
  32 + uint32_t cr;
  33 + uint32_t upbase;
  34 + uint32_t lpbase;
  35 + uint32_t int_status;
  36 + uint32_t int_mask;
  37 + int cols;
  38 + int rows;
  39 + enum pl110_bppmode bpp;
  40 + int invalidate;
  41 + uint32_t pallette[256];
  42 + uint32_t raw_pallette[128];
  43 + int irq;
  44 +} pl110_state;
  45 +
  46 +static const unsigned char pl110_id[] =
  47 +{ 0x10, 0x11, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
  48 +
  49 +static inline uint32_t rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
  50 +{
  51 + return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
  52 +}
  53 +
  54 +static inline uint32_t rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
  55 +{
  56 + return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
  57 +}
  58 +
  59 +static inline uint32_t rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
  60 +{
  61 + return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
  62 +}
  63 +
  64 +static inline uint32_t rgb_to_pixel24(unsigned int r, unsigned int g, unsigned b)
  65 +{
  66 + return (r << 16) | (g << 8) | b;
  67 +}
  68 +
  69 +static inline uint32_t rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
  70 +{
  71 + return (r << 16) | (g << 8) | b;
  72 +}
  73 +
  74 +typedef void (*drawfn)(uint32_t *, uint8_t *, const uint8_t *, int);
  75 +
  76 +#define BITS 8
  77 +#include "pl110_template.h"
  78 +#define BITS 15
  79 +#include "pl110_template.h"
  80 +#define BITS 16
  81 +#include "pl110_template.h"
  82 +#define BITS 24
  83 +#include "pl110_template.h"
  84 +#define BITS 32
  85 +#include "pl110_template.h"
  86 +
  87 +static int pl110_enabled(pl110_state *s)
  88 +{
  89 + return (s->cr & PL110_CR_EN) && (s->cr & PL110_CR_PWR);
  90 +}
  91 +
  92 +void pl110_update_display(void *opaque)
  93 +{
  94 + pl110_state *s = (pl110_state *)opaque;
  95 + drawfn* fntable;
  96 + drawfn fn;
  97 + uint32_t *pallette;
  98 + uint32_t addr;
  99 + uint32_t base;
  100 + int dest_width;
  101 + int src_width;
  102 + uint8_t *dest;
  103 + uint8_t *src;
  104 + int first, last;
  105 + int dirty, new_dirty;
  106 + int i;
  107 +
  108 + if (!pl110_enabled(s))
  109 + return;
  110 +
  111 + switch (s->ds->depth) {
  112 + case 8:
  113 + fntable = pl110_draw_fn_8;
  114 + dest_width = 1;
  115 + break;
  116 + case 15:
  117 + fntable = pl110_draw_fn_15;
  118 + dest_width = 2;
  119 + break;
  120 + case 16:
  121 + fntable = pl110_draw_fn_16;
  122 + dest_width = 2;
  123 + break;
  124 + case 24:
  125 + fntable = pl110_draw_fn_24;
  126 + dest_width = 3;
  127 + break;
  128 + case 32:
  129 + fntable = pl110_draw_fn_32;
  130 + dest_width = 4;
  131 + break;
  132 + default:
  133 + fprintf(stderr, "qemu: Bad color depth\n");
  134 + exit(1);
  135 + }
  136 + if (s->cr & PL110_CR_BEBO)
  137 + fn = fntable[s->bpp + 6];
  138 + else if (s->cr & PL110_CR_BEPO)
  139 + fn = fntable[s->bpp + 12];
  140 + else
  141 + fn = fntable[s->bpp];
  142 +
  143 + src_width = s->cols;
  144 + switch (s->bpp) {
  145 + case BPP_1:
  146 + src_width >>= 3;
  147 + break;
  148 + case BPP_2:
  149 + src_width >>= 2;
  150 + break;
  151 + case BPP_4:
  152 + src_width >>= 1;
  153 + break;
  154 + case BPP_8:
  155 + break;
  156 + case BPP_16:
  157 + src_width <<= 1;
  158 + break;
  159 + case BPP_32:
  160 + src_width <<= 2;
  161 + break;
  162 + }
  163 + dest_width *= s->cols;
  164 + pallette = s->pallette;
  165 + base = s->upbase;
  166 + /* HACK: Arm aliases physical memory at 0x80000000. */
  167 + if (base > 0x80000000)
  168 + base -= 0x80000000;
  169 + src = phys_ram_base + base;
  170 + dest = s->ds->data;
  171 + first = -1;
  172 + addr = base;
  173 +
  174 + dirty = cpu_physical_memory_get_dirty(addr, VGA_DIRTY_FLAG);
  175 + for (i = 0; i < s->rows; i++) {
  176 + new_dirty = 0;
  177 + if ((addr & TARGET_PAGE_MASK) + src_width >= TARGET_PAGE_SIZE) {
  178 + uint32_t tmp;
  179 + for (tmp = 0; tmp < src_width; tmp += TARGET_PAGE_SIZE) {
  180 + new_dirty |= cpu_physical_memory_get_dirty(addr + tmp,
  181 + VGA_DIRTY_FLAG);
  182 + }
  183 + }
  184 +
  185 + if (dirty || new_dirty || s->invalidate) {
  186 + fn(pallette, dest, src, s->cols);
  187 + if (first == -1)
  188 + first = i;
  189 + last = i;
  190 + }
  191 + dirty = new_dirty;
  192 + addr += src_width;
  193 + dest += dest_width;
  194 + src += src_width;
  195 + }
  196 + if (first < 0)
  197 + return;
  198 +
  199 + s->invalidate = 0;
  200 + cpu_physical_memory_reset_dirty(base + first * src_width,
  201 + base + (last + 1) * src_width,
  202 + VGA_DIRTY_FLAG);
  203 + dpy_update(s->ds, 0, first, s->cols, last - first + 1);
  204 +}
  205 +
  206 +void pl110_invalidate_display(void * opaque)
  207 +{
  208 + pl110_state *s = (pl110_state *)opaque;
  209 + s->invalidate = 1;
  210 +}
  211 +
  212 +static void pl110_update_pallette(pl110_state *s, int n)
  213 +{
  214 + int i;
  215 + uint32_t raw;
  216 + unsigned int r, g, b;
  217 +
  218 + raw = s->raw_pallette[n];
  219 + n <<= 1;
  220 + for (i = 0; i < 2; i++) {
  221 + r = (raw & 0x1f) << 3;
  222 + raw >>= 5;
  223 + g = (raw & 0x1f) << 3;
  224 + raw >>= 5;
  225 + b = (raw & 0x1f) << 3;
  226 + /* The I bit is ignored. */
  227 + raw >>= 6;
  228 + switch (s->ds->depth) {
  229 + case 8:
  230 + s->pallette[n] = rgb_to_pixel8(r, g, b);
  231 + break;
  232 + case 15:
  233 + s->pallette[n] = rgb_to_pixel15(r, g, b);
  234 + break;
  235 + case 16:
  236 + s->pallette[n] = rgb_to_pixel16(r, g, b);
  237 + break;
  238 + case 24:
  239 + case 32:
  240 + s->pallette[n] = rgb_to_pixel32(r, g, b);
  241 + break;
  242 + }
  243 + n++;
  244 + }
  245 +}
  246 +
  247 +static void pl110_resize(pl110_state *s, int width, int height)
  248 +{
  249 + if (width != s->cols || height != s->rows) {
  250 + if (pl110_enabled(s)) {
  251 + dpy_resize(s->ds, s->cols, s->rows);
  252 + }
  253 + }
  254 + s->cols = width;
  255 + s->rows = height;
  256 +}
  257 +
  258 +/* Update interrupts. */
  259 +static void pl110_update(pl110_state *s)
  260 +{
  261 + /* TODO: Implement interrupts. */
  262 +}
  263 +
  264 +static uint32_t pl110_read(void *opaque, target_phys_addr_t offset)
  265 +{
  266 + pl110_state *s = (pl110_state *)opaque;
  267 +
  268 + offset -= s->base;
  269 + if (offset >= 0xfe0 && offset < 0x1000) {
  270 + return pl110_id[(offset - 0xfe0) >> 2];
  271 + }
  272 + if (offset >= 0x200 && offset < 0x400) {
  273 + return s->raw_pallette[(offset - 0x200) >> 2];
  274 + }
  275 + switch (offset >> 2) {
  276 + case 0: /* LCDTiming0 */
  277 + return s->timing[0];
  278 + case 1: /* LCDTiming1 */
  279 + return s->timing[1];
  280 + case 2: /* LCDTiming2 */
  281 + return s->timing[2];
  282 + case 3: /* LCDTiming3 */
  283 + return s->timing[3];
  284 + case 4: /* LCDUPBASE */
  285 + return s->upbase;
  286 + case 5: /* LCDLPBASE */
  287 + return s->lpbase;
  288 + case 6: /* LCDIMSC */
  289 + return s->int_mask;
  290 + case 7: /* LCDControl */
  291 + return s->cr;
  292 + case 8: /* LCDRIS */
  293 + return s->int_status;
  294 + case 9: /* LCDMIS */
  295 + return s->int_status & s->int_mask;
  296 + case 11: /* LCDUPCURR */
  297 + /* TODO: Implement vertical refresh. */
  298 + return s->upbase;
  299 + case 12: /* LCDLPCURR */
  300 + return s->lpbase;
  301 + default:
  302 + cpu_abort (cpu_single_env, "pl110_read: Bad offset %x\n", offset);
  303 + return 0;
  304 + }
  305 +}
  306 +
  307 +static void pl110_write(void *opaque, target_phys_addr_t offset,
  308 + uint32_t val)
  309 +{
  310 + pl110_state *s = (pl110_state *)opaque;
  311 + int n;
  312 +
  313 + /* For simplicity invalidate the display whenever a control register
  314 + is writen to. */
  315 + s->invalidate = 1;
  316 + offset -= s->base;
  317 + if (offset >= 0x200 && offset < 0x400) {
  318 + /* Pallette. */
  319 + n = (offset - 0x200) >> 2;
  320 + s->raw_pallette[(offset - 0x200) >> 2] = val;
  321 + pl110_update_pallette(s, n);
  322 + }
  323 + switch (offset >> 2) {
  324 + case 0: /* LCDTiming0 */
  325 + s->timing[0] = val;
  326 + n = ((val & 0xfc) + 4) * 4;
  327 + pl110_resize(s, n, s->rows);
  328 + break;
  329 + case 1: /* LCDTiming1 */
  330 + s->timing[1] = val;
  331 + n = (val & 0x3ff) + 1;
  332 + pl110_resize(s, s->cols, n);
  333 + break;
  334 + case 2: /* LCDTiming2 */
  335 + s->timing[2] = val;
  336 + break;
  337 + case 3: /* LCDTiming3 */
  338 + s->timing[3] = val;
  339 + break;
  340 + case 4: /* LCDUPBASE */
  341 + s->upbase = val;
  342 + break;
  343 + case 5: /* LCDLPBASE */
  344 + s->lpbase = val;
  345 + break;
  346 + case 6: /* LCDIMSC */
  347 + s->int_mask = val;
  348 + pl110_update(s);
  349 + break;
  350 + case 7: /* LCDControl */
  351 + s->cr = val;
  352 + s->bpp = (val >> 1) & 7;
  353 + if (pl110_enabled(s)) {
  354 + dpy_resize(s->ds, s->cols, s->rows);
  355 + }
  356 + break;
  357 + case 10: /* LCDICR */
  358 + s->int_status &= ~val;
  359 + pl110_update(s);
  360 + break;
  361 + default:
  362 + cpu_abort (cpu_single_env, "pl110_write: Bad offset %x\n", offset);
  363 + }
  364 +}
  365 +
  366 +static CPUReadMemoryFunc *pl110_readfn[] = {
  367 + pl110_read,
  368 + pl110_read,
  369 + pl110_read
  370 +};
  371 +
  372 +static CPUWriteMemoryFunc *pl110_writefn[] = {
  373 + pl110_write,
  374 + pl110_write,
  375 + pl110_write
  376 +};
  377 +
  378 +void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq)
  379 +{
  380 + pl110_state *s;
  381 + int iomemtype;
  382 +
  383 + s = (pl110_state *)qemu_mallocz(sizeof(pl110_state));
  384 + iomemtype = cpu_register_io_memory(0, pl110_readfn,
  385 + pl110_writefn, s);
  386 + cpu_register_physical_memory(base, 0x007fffff, iomemtype);
  387 + s->base = base;
  388 + s->ds = ds;
  389 + s->pic = pic;
  390 + s->irq = irq;
  391 + /* ??? Save/restore. */
  392 + return s;
  393 +}
... ...
hw/pl110_template.h 0 → 100644
  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 licenced under the GNU LGPL
  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
  17 +#define COPY_PIXEL(to, from) *(uint16_t *)to = from; to += 2;
  18 +#elif BITS == 24
  19 +#define COPY_PIXEL(to, from) \
  20 + *(to++) = from; *(to++) = (from) >> 8; *(to++) = (from) >> 16
  21 +#elif BITS == 32
  22 +#define COPY_PIXEL(to, from) *(uint32_t *)to = from; to += 4;
  23 +#else
  24 +#error unknown bit depth
  25 +#endif
  26 +
  27 +#define ORDER 0
  28 +#include "pl110_template.h"
  29 +#define ORDER 1
  30 +#include "pl110_template.h"
  31 +#define ORDER 2
  32 +#include "pl110_template.h"
  33 +
  34 +static drawfn glue(pl110_draw_fn_,BITS)[18] =
  35 +{
  36 + glue(pl110_draw_line1_lblp,BITS),
  37 + glue(pl110_draw_line2_lblp,BITS),
  38 + glue(pl110_draw_line4_lblp,BITS),
  39 + glue(pl110_draw_line8_lblp,BITS),
  40 + glue(pl110_draw_line16_lblp,BITS),
  41 + glue(pl110_draw_line32_lblp,BITS),
  42 +
  43 + glue(pl110_draw_line1_bbbp,BITS),
  44 + glue(pl110_draw_line2_bbbp,BITS),
  45 + glue(pl110_draw_line4_bbbp,BITS),
  46 + glue(pl110_draw_line8_bbbp,BITS),
  47 + glue(pl110_draw_line16_bbbp,BITS),
  48 + glue(pl110_draw_line32_bbbp,BITS),
  49 +
  50 + glue(pl110_draw_line1_lbbp,BITS),
  51 + glue(pl110_draw_line2_lbbp,BITS),
  52 + glue(pl110_draw_line4_lbbp,BITS),
  53 + glue(pl110_draw_line8_lbbp,BITS),
  54 + glue(pl110_draw_line16_lbbp,BITS),
  55 + glue(pl110_draw_line32_lbbp,BITS)
  56 +};
  57 +
  58 +#undef BITS
  59 +#undef COPY_PIXEL
  60 +
  61 +#else
  62 +
  63 +#if ORDER == 0
  64 +#define NAME glue(lblp, BITS)
  65 +#ifdef WORDS_BIGENDIAN
  66 +#define SWAP_WORDS 1
  67 +#endif
  68 +#elif ORDER == 1
  69 +#define NAME glue(bbbp, BITS)
  70 +#ifndef WORDS_BIGENDIAN
  71 +#define SWAP_WORDS 1
  72 +#endif
  73 +#else
  74 +#define SWAP_PIXELS 1
  75 +#define NAME glue(lbbp, BITS)
  76 +#ifdef WORDS_BIGENDIAN
  77 +#define SWAP_WORDS 1
  78 +#endif
  79 +#endif
  80 +
  81 +#define FN_2(x, y) FN(x, y) FN(x+1, y)
  82 +#define FN_4(x, y) FN_2(x, y) FN_2(x+1, y)
  83 +#define FN_8(y) FN_4(0, y) FN_4(4, y)
  84 +
  85 +static void glue(pl110_draw_line1_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
  86 +{
  87 + uint32_t data;
  88 + while (width > 0) {
  89 + data = *(uint32_t *)src;
  90 +#ifdef SWAP_PIXELS
  91 +#define FN(x, y) COPY_PIXEL(d, pallette[(data >> (y + 7 - (x))) & 1]);
  92 +#else
  93 +#define FN(x, y) COPY_PIXEL(d, pallette[(data >> ((x) + y)) & 1]);
  94 +#endif
  95 +#ifdef SWAP_BYTES
  96 + FN_8(24)
  97 + FN_8(16)
  98 + FN_8(8)
  99 + FN_8(0)
  100 +#else
  101 + FN_8(0)
  102 + FN_8(8)
  103 + FN_8(16)
  104 + FN_8(24)
  105 +#endif
  106 +#undef FN
  107 + width -= 32;
  108 + src += 4;
  109 + }
  110 +}
  111 +
  112 +static void glue(pl110_draw_line2_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
  113 +{
  114 + uint32_t data;
  115 + while (width > 0) {
  116 + data = *(uint32_t *)src;
  117 +#ifdef SWAP_PIXELS
  118 +#define FN(x, y) COPY_PIXEL(d, pallette[(data >> (y + 6 - (x)*2)) & 3]);
  119 +#else
  120 +#define FN(x, y) COPY_PIXEL(d, pallette[(data >> ((x)*2 + y)) & 3]);
  121 +#endif
  122 +#ifdef SWAP_BYTES
  123 + FN_4(0, 24)
  124 + FN_4(0, 16)
  125 + FN_4(0, 8)
  126 + FN_4(0, 0)
  127 +#else
  128 + FN_4(0, 0)
  129 + FN_4(0, 8)
  130 + FN_4(0, 16)
  131 + FN_4(0, 24)
  132 +#endif
  133 +#undef FN
  134 + width -= 16;
  135 + src += 4;
  136 + }
  137 +}
  138 +
  139 +static void glue(pl110_draw_line4_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
  140 +{
  141 + uint32_t data;
  142 + while (width > 0) {
  143 + data = *(uint32_t *)src;
  144 +#ifdef SWAP_PIXELS
  145 +#define FN(x, y) COPY_PIXEL(d, pallette[(data >> (y + 4 - (x)*4)) & 0xf]);
  146 +#else
  147 +#define FN(x, y) COPY_PIXEL(d, pallette[(data >> ((x)*4 + y)) & 0xf]);
  148 +#endif
  149 +#ifdef SWAP_BYTES
  150 + FN_2(0, 24)
  151 + FN_2(0, 16)
  152 + FN_2(0, 8)
  153 + FN_2(0, 0)
  154 +#else
  155 + FN_2(0, 0)
  156 + FN_2(0, 8)
  157 + FN_2(0, 16)
  158 + FN_2(0, 24)
  159 +#endif
  160 +#undef FN
  161 + width -= 8;
  162 + src += 4;
  163 + }
  164 +}
  165 +
  166 +static void glue(pl110_draw_line8_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
  167 +{
  168 + uint32_t data;
  169 + while (width > 0) {
  170 + data = *(uint32_t *)src;
  171 +#define FN(x) COPY_PIXEL(d, pallette[(data >> (x)) & 0xff]);
  172 +#ifdef SWAP_BYTES
  173 + FN(24)
  174 + FN(16)
  175 + FN(8)
  176 + FN(0)
  177 +#else
  178 + FN(0)
  179 + FN(8)
  180 + FN(16)
  181 + FN(24)
  182 +#endif
  183 +#undef FN
  184 + width -= 4;
  185 + src += 4;
  186 + }
  187 +}
  188 +
  189 +static void glue(pl110_draw_line16_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
  190 +{
  191 + uint32_t data;
  192 + unsigned int r, g, b;
  193 + while (width > 0) {
  194 + data = *(uint32_t *)src;
  195 +#ifdef SWAP_BYTES
  196 + data = bswap32(data);
  197 +#endif
  198 +#if 0
  199 + r = data & 0x1f;
  200 + data >>= 5;
  201 + g = data & 0x3f;
  202 + data >>= 6;
  203 + b = data & 0x1f;
  204 + data >>= 5;
  205 +#else
  206 + r = (data & 0x1f) << 3;
  207 + data >>= 5;
  208 + g = (data & 0x3f) << 2;
  209 + data >>= 6;
  210 + b = (data & 0x1f) << 3;
  211 + data >>= 5;
  212 +#endif
  213 + COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
  214 + r = (data & 0x1f) << 3;
  215 + data >>= 5;
  216 + g = (data & 0x3f) << 2;
  217 + data >>= 6;
  218 + b = (data & 0x1f) << 3;
  219 + data >>= 5;
  220 + COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
  221 + width -= 2;
  222 + src += 4;
  223 + }
  224 +}
  225 +
  226 +static void glue(pl110_draw_line32_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
  227 +{
  228 + uint32_t data;
  229 + unsigned int r, g, b;
  230 + while (width > 0) {
  231 + data = *(uint32_t *)src;
  232 +#ifdef SWAP_BYTES
  233 + r = data & 0xff;
  234 + g = (data >> 8) & 0xff;
  235 + b = (data >> 16) & 0xff;
  236 +#else
  237 + r = (data >> 24) & 0xff;
  238 + g = (data >> 16) & 0xff;
  239 + b = (data >> 8) & 0xff;
  240 +#endif
  241 + COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
  242 + width--;
  243 + src += 4;
  244 + }
  245 +}
  246 +
  247 +#undef SWAP_PIXELS
  248 +#undef NAME
  249 +#undef SWAP_WORDS
  250 +#undef ORDER
  251 +
  252 +#endif
... ...
... ... @@ -973,6 +973,11 @@ void ps2_queue(void *, int b);
973 973 /* smc91c111.c */
974 974 void smc91c111_init(NICInfo *, uint32_t, void *, int);
975 975  
  976 +/* pl110.c */
  977 +void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq);
  978 +void pl110_update_display(void *opaque);
  979 +void pl110_invalidate_display(void *opaque);
  980 +
976 981 #endif /* defined(QEMU_TOOL) */
977 982  
978 983 /* monitor.c */
... ...