summaryrefslogtreecommitdiff
path: root/hw/display
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2013-03-18 17:36:02 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2013-04-08 18:13:16 +0200
commit47b43a1f414c5b3eb9eb7502d0b0be0d134259ba (patch)
tree9acfd03f458083a077ac79bd462d5360916f445f /hw/display
parent8d8b636d28a97af7bf43c3267d07f87b9530939a (diff)
downloadqemu-47b43a1f414c5b3eb9eb7502d0b0be0d134259ba.tar.gz
hw: move private headers to hw/ subdirectories.
Many headers are used only in a single directory. These can be kept in hw/. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/display')
-rw-r--r--hw/display/blizzard.c12
-rw-r--r--hw/display/blizzard_template.h136
-rw-r--r--hw/display/cirrus_vga.c38
-rw-r--r--hw/display/cirrus_vga_rop.h208
-rw-r--r--hw/display/cirrus_vga_rop2.h281
-rw-r--r--hw/display/cirrus_vga_template.h102
-rw-r--r--hw/display/framebuffer.c2
-rw-r--r--hw/display/framebuffer.h25
-rw-r--r--hw/display/milkymist-vgafb.c12
-rw-r--r--hw/display/milkymist-vgafb_template.h74
-rw-r--r--hw/display/omap_lcd_template.h175
-rw-r--r--hw/display/omap_lcdc.c10
-rw-r--r--hw/display/pl110.c12
-rw-r--r--hw/display/pl110_template.h395
-rw-r--r--hw/display/pxa2xx_lcd.c12
-rw-r--r--hw/display/pxa2xx_template.h435
-rw-r--r--hw/display/qxl-logger.c2
-rw-r--r--hw/display/qxl-render.c2
-rw-r--r--hw/display/qxl.c2
-rw-r--r--hw/display/qxl.h165
-rw-r--r--hw/display/sm501.c14
-rw-r--r--hw/display/sm501_template.h145
-rw-r--r--hw/display/tc6393xb.c10
-rw-r--r--hw/display/tc6393xb_template.h68
-rw-r--r--hw/display/vga-isa-mm.c2
-rw-r--r--hw/display/vga-isa.c2
-rw-r--r--hw/display/vga-pci.c2
-rw-r--r--hw/display/vga.c18
-rw-r--r--hw/display/vga.h159
-rw-r--r--hw/display/vga_int.h218
-rw-r--r--hw/display/vga_template.h459
-rw-r--r--hw/display/vmware_vga.c2
32 files changed, 3122 insertions, 77 deletions
diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c
index bdb0b15ddb..175c5cdd00 100644
--- a/hw/display/blizzard.c
+++ b/hw/display/blizzard.c
@@ -21,7 +21,7 @@
#include "qemu-common.h"
#include "ui/console.h"
#include "hw/arm/devices.h"
-#include "hw/vga_int.h"
+#include "vga_int.h"
#include "ui/pixel_ops.h"
typedef void (*blizzard_fn_t)(uint8_t *, const uint8_t *, unsigned int);
@@ -946,15 +946,15 @@ static void blizzard_screen_dump(void *opaque, const char *filename,
}
#define DEPTH 8
-#include "hw/blizzard_template.h"
+#include "blizzard_template.h"
#define DEPTH 15
-#include "hw/blizzard_template.h"
+#include "blizzard_template.h"
#define DEPTH 16
-#include "hw/blizzard_template.h"
+#include "blizzard_template.h"
#define DEPTH 24
-#include "hw/blizzard_template.h"
+#include "blizzard_template.h"
#define DEPTH 32
-#include "hw/blizzard_template.h"
+#include "blizzard_template.h"
void *s1d13745_init(qemu_irq gpio_int)
{
diff --git a/hw/display/blizzard_template.h b/hw/display/blizzard_template.h
new file mode 100644
index 0000000000..a8a8899478
--- /dev/null
+++ b/hw/display/blizzard_template.h
@@ -0,0 +1,136 @@
+/*
+ * QEMU Epson S1D13744/S1D13745 templates
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Written by Andrzej Zaborowski <andrew@openedhand.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define SKIP_PIXEL(to) to += deststep
+#if DEPTH == 8
+# define PIXEL_TYPE uint8_t
+# define COPY_PIXEL(to, from) *to = from; SKIP_PIXEL(to)
+# define COPY_PIXEL1(to, from) *to ++ = from
+#elif DEPTH == 15 || DEPTH == 16
+# define PIXEL_TYPE uint16_t
+# define COPY_PIXEL(to, from) *to = from; SKIP_PIXEL(to)
+# define COPY_PIXEL1(to, from) *to ++ = from
+#elif DEPTH == 24
+# define PIXEL_TYPE uint8_t
+# define COPY_PIXEL(to, from) \
+ to[0] = from; to[1] = (from) >> 8; to[2] = (from) >> 16; SKIP_PIXEL(to)
+# define COPY_PIXEL1(to, from) \
+ *to ++ = from; *to ++ = (from) >> 8; *to ++ = (from) >> 16
+#elif DEPTH == 32
+# define PIXEL_TYPE uint32_t
+# define COPY_PIXEL(to, from) *to = from; SKIP_PIXEL(to)
+# define COPY_PIXEL1(to, from) *to ++ = from
+#else
+# error unknown bit depth
+#endif
+
+#ifdef HOST_WORDS_BIGENDIAN
+# define SWAP_WORDS 1
+#endif
+
+static void glue(blizzard_draw_line16_, DEPTH)(PIXEL_TYPE *dest,
+ const uint16_t *src, unsigned int width)
+{
+#if !defined(SWAP_WORDS) && DEPTH == 16
+ memcpy(dest, src, width);
+#else
+ uint16_t data;
+ unsigned int r, g, b;
+ const uint16_t *end = (const void *) src + width;
+ while (src < end) {
+ data = *src ++;
+ b = (data & 0x1f) << 3;
+ data >>= 5;
+ g = (data & 0x3f) << 2;
+ data >>= 6;
+ r = (data & 0x1f) << 3;
+ data >>= 5;
+ COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b));
+ }
+#endif
+}
+
+static void glue(blizzard_draw_line24mode1_, DEPTH)(PIXEL_TYPE *dest,
+ const uint8_t *src, unsigned int width)
+{
+ /* TODO: check if SDL 24-bit planes are not in the same format and
+ * if so, use memcpy */
+ unsigned int r[2], g[2], b[2];
+ const uint8_t *end = src + width;
+ while (src < end) {
+ g[0] = *src ++;
+ r[0] = *src ++;
+ r[1] = *src ++;
+ b[0] = *src ++;
+ COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r[0], g[0], b[0]));
+ b[1] = *src ++;
+ g[1] = *src ++;
+ COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r[1], g[1], b[1]));
+ }
+}
+
+static void glue(blizzard_draw_line24mode2_, DEPTH)(PIXEL_TYPE *dest,
+ const uint8_t *src, unsigned int width)
+{
+ unsigned int r, g, b;
+ const uint8_t *end = src + width;
+ while (src < end) {
+ r = *src ++;
+ src ++;
+ b = *src ++;
+ g = *src ++;
+ COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b));
+ }
+}
+
+/* No rotation */
+static blizzard_fn_t glue(blizzard_draw_fn_, DEPTH)[0x10] = {
+ NULL,
+ /* RGB 5:6:5*/
+ (blizzard_fn_t) glue(blizzard_draw_line16_, DEPTH),
+ /* RGB 6:6:6 mode 1 */
+ (blizzard_fn_t) glue(blizzard_draw_line24mode1_, DEPTH),
+ /* RGB 8:8:8 mode 1 */
+ (blizzard_fn_t) glue(blizzard_draw_line24mode1_, DEPTH),
+ NULL, NULL,
+ /* RGB 6:6:6 mode 2 */
+ (blizzard_fn_t) glue(blizzard_draw_line24mode2_, DEPTH),
+ /* RGB 8:8:8 mode 2 */
+ (blizzard_fn_t) glue(blizzard_draw_line24mode2_, DEPTH),
+ /* YUV 4:2:2 */
+ NULL,
+ /* YUV 4:2:0 */
+ NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
+/* 90deg, 180deg and 270deg rotation */
+static blizzard_fn_t glue(blizzard_draw_fn_r_, DEPTH)[0x10] = {
+ /* TODO */
+ [0 ... 0xf] = NULL,
+};
+
+#undef DEPTH
+#undef SKIP_PIXEL
+#undef COPY_PIXEL
+#undef COPY_PIXEL1
+#undef PIXEL_TYPE
+
+#undef SWAP_WORDS
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index 7a4d63436e..bf2181afd8 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -29,7 +29,7 @@
#include "hw/hw.h"
#include "hw/pci/pci.h"
#include "ui/console.h"
-#include "hw/vga_int.h"
+#include "vga_int.h"
#include "hw/loader.h"
/*
@@ -288,63 +288,63 @@ static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
#define ROP_NAME 0
#define ROP_FN(d, s) 0
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME src_and_dst
#define ROP_FN(d, s) (s) & (d)
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME src_and_notdst
#define ROP_FN(d, s) (s) & (~(d))
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME notdst
#define ROP_FN(d, s) ~(d)
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME src
#define ROP_FN(d, s) s
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME 1
#define ROP_FN(d, s) ~0
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME notsrc_and_dst
#define ROP_FN(d, s) (~(s)) & (d)
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME src_xor_dst
#define ROP_FN(d, s) (s) ^ (d)
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME src_or_dst
#define ROP_FN(d, s) (s) | (d)
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME notsrc_or_notdst
#define ROP_FN(d, s) (~(s)) | (~(d))
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME src_notxor_dst
#define ROP_FN(d, s) ~((s) ^ (d))
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME src_or_notdst
#define ROP_FN(d, s) (s) | (~(d))
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME notsrc
#define ROP_FN(d, s) (~(s))
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME notsrc_or_dst
#define ROP_FN(d, s) (~(s)) | (d)
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
#define ROP_NAME notsrc_and_notdst
#define ROP_FN(d, s) (~(s)) & (~(d))
-#include "hw/cirrus_vga_rop.h"
+#include "cirrus_vga_rop.h"
static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
cirrus_bitblt_rop_fwd_0,
@@ -2166,13 +2166,13 @@ static void cirrus_cursor_invalidate(VGACommonState *s1)
}
#define DEPTH 8
-#include "hw/cirrus_vga_template.h"
+#include "cirrus_vga_template.h"
#define DEPTH 16
-#include "hw/cirrus_vga_template.h"
+#include "cirrus_vga_template.h"
#define DEPTH 32
-#include "hw/cirrus_vga_template.h"
+#include "cirrus_vga_template.h"
static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
{
diff --git a/hw/display/cirrus_vga_rop.h b/hw/display/cirrus_vga_rop.h
new file mode 100644
index 0000000000..9c7bb09286
--- /dev/null
+++ b/hw/display/cirrus_vga_rop.h
@@ -0,0 +1,208 @@
+/*
+ * QEMU Cirrus CLGD 54xx VGA Emulator.
+ *
+ * Copyright (c) 2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+static inline void glue(rop_8_,ROP_NAME)(uint8_t *dst, uint8_t src)
+{
+ *dst = ROP_FN(*dst, src);
+}
+
+static inline void glue(rop_16_,ROP_NAME)(uint16_t *dst, uint16_t src)
+{
+ *dst = ROP_FN(*dst, src);
+}
+
+static inline void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src)
+{
+ *dst = ROP_FN(*dst, src);
+}
+
+#define ROP_OP(d, s) glue(rop_8_,ROP_NAME)(d, s)
+#define ROP_OP_16(d, s) glue(rop_16_,ROP_NAME)(d, s)
+#define ROP_OP_32(d, s) glue(rop_32_,ROP_NAME)(d, s)
+#undef ROP_FN
+
+static void
+glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
+ uint8_t *dst,const uint8_t *src,
+ int dstpitch,int srcpitch,
+ int bltwidth,int bltheight)
+{
+ int x,y;
+ dstpitch -= bltwidth;
+ srcpitch -= bltwidth;
+
+ if (dstpitch < 0 || srcpitch < 0) {
+ /* is 0 valid? srcpitch == 0 could be useful */
+ return;
+ }
+
+ for (y = 0; y < bltheight; y++) {
+ for (x = 0; x < bltwidth; x++) {
+ ROP_OP(dst, *src);
+ dst++;
+ src++;
+ }
+ dst += dstpitch;
+ src += srcpitch;
+ }
+}
+
+static void
+glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
+ uint8_t *dst,const uint8_t *src,
+ int dstpitch,int srcpitch,
+ int bltwidth,int bltheight)
+{
+ int x,y;
+ dstpitch += bltwidth;
+ srcpitch += bltwidth;
+ for (y = 0; y < bltheight; y++) {
+ for (x = 0; x < bltwidth; x++) {
+ ROP_OP(dst, *src);
+ dst--;
+ src--;
+ }
+ dst += dstpitch;
+ src += srcpitch;
+ }
+}
+
+static void
+glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
+ uint8_t *dst,const uint8_t *src,
+ int dstpitch,int srcpitch,
+ int bltwidth,int bltheight)
+{
+ int x,y;
+ uint8_t p;
+ dstpitch -= bltwidth;
+ srcpitch -= bltwidth;
+ for (y = 0; y < bltheight; y++) {
+ for (x = 0; x < bltwidth; x++) {
+ p = *dst;
+ ROP_OP(&p, *src);
+ if (p != s->vga.gr[0x34]) *dst = p;
+ dst++;
+ src++;
+ }
+ dst += dstpitch;
+ src += srcpitch;
+ }
+}
+
+static void
+glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
+ uint8_t *dst,const uint8_t *src,
+ int dstpitch,int srcpitch,
+ int bltwidth,int bltheight)
+{
+ int x,y;
+ uint8_t p;
+ dstpitch += bltwidth;
+ srcpitch += bltwidth;
+ for (y = 0; y < bltheight; y++) {
+ for (x = 0; x < bltwidth; x++) {
+ p = *dst;
+ ROP_OP(&p, *src);
+ if (p != s->vga.gr[0x34]) *dst = p;
+ dst--;
+ src--;
+ }
+ dst += dstpitch;
+ src += srcpitch;
+ }
+}
+
+static void
+glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
+ uint8_t *dst,const uint8_t *src,
+ int dstpitch,int srcpitch,
+ int bltwidth,int bltheight)
+{
+ int x,y;
+ uint8_t p1, p2;
+ dstpitch -= bltwidth;
+ srcpitch -= bltwidth;
+ for (y = 0; y < bltheight; y++) {
+ for (x = 0; x < bltwidth; x+=2) {
+ p1 = *dst;
+ p2 = *(dst+1);
+ ROP_OP(&p1, *src);
+ ROP_OP(&p2, *(src + 1));
+ if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) {
+ *dst = p1;
+ *(dst+1) = p2;
+ }
+ dst+=2;
+ src+=2;
+ }
+ dst += dstpitch;
+ src += srcpitch;
+ }
+}
+
+static void
+glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
+ uint8_t *dst,const uint8_t *src,
+ int dstpitch,int srcpitch,
+ int bltwidth,int bltheight)
+{
+ int x,y;
+ uint8_t p1, p2;
+ dstpitch += bltwidth;
+ srcpitch += bltwidth;
+ for (y = 0; y < bltheight; y++) {
+ for (x = 0; x < bltwidth; x+=2) {
+ p1 = *(dst-1);
+ p2 = *dst;
+ ROP_OP(&p1, *(src - 1));
+ ROP_OP(&p2, *src);
+ if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) {
+ *(dst-1) = p1;
+ *dst = p2;
+ }
+ dst-=2;
+ src-=2;
+ }
+ dst += dstpitch;
+ src += srcpitch;
+ }
+}
+
+#define DEPTH 8
+#include "cirrus_vga_rop2.h"
+
+#define DEPTH 16
+#include "cirrus_vga_rop2.h"
+
+#define DEPTH 24
+#include "cirrus_vga_rop2.h"
+
+#define DEPTH 32
+#include "cirrus_vga_rop2.h"
+
+#undef ROP_NAME
+#undef ROP_OP
+#undef ROP_OP_16
+#undef ROP_OP_32
diff --git a/hw/display/cirrus_vga_rop2.h b/hw/display/cirrus_vga_rop2.h
new file mode 100644
index 0000000000..d28bcc6f25
--- /dev/null
+++ b/hw/display/cirrus_vga_rop2.h
@@ -0,0 +1,281 @@
+/*
+ * QEMU Cirrus CLGD 54xx VGA Emulator.
+ *
+ * Copyright (c) 2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if DEPTH == 8
+#define PUTPIXEL() ROP_OP(&d[0], col)
+#elif DEPTH == 16
+#define PUTPIXEL() ROP_OP_16((uint16_t *)&d[0], col)
+#elif DEPTH == 24
+#define PUTPIXEL() ROP_OP(&d[0], col); \
+ ROP_OP(&d[1], (col >> 8)); \
+ ROP_OP(&d[2], (col >> 16))
+#elif DEPTH == 32
+#define PUTPIXEL() ROP_OP_32(((uint32_t *)&d[0]), col)
+#else
+#error unsupported DEPTH
+#endif
+
+static void
+glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
+ (CirrusVGAState * s, uint8_t * dst,
+ const uint8_t * src,
+ int dstpitch, int srcpitch,
+ int bltwidth, int bltheight)
+{
+ uint8_t *d;
+ int x, y, pattern_y, pattern_pitch, pattern_x;
+ unsigned int col;
+ const uint8_t *src1;
+#if DEPTH == 24
+ int skipleft = s->vga.gr[0x2f] & 0x1f;
+#else
+ int skipleft = (s->vga.gr[0x2f] & 0x07) * (DEPTH / 8);
+#endif
+
+#if DEPTH == 8
+ pattern_pitch = 8;
+#elif DEPTH == 16
+ pattern_pitch = 16;
+#else
+ pattern_pitch = 32;
+#endif
+ pattern_y = s->cirrus_blt_srcaddr & 7;
+ for(y = 0; y < bltheight; y++) {
+ pattern_x = skipleft;
+ d = dst + skipleft;
+ src1 = src + pattern_y * pattern_pitch;
+ for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
+#if DEPTH == 8
+ col = src1[pattern_x];
+ pattern_x = (pattern_x + 1) & 7;
+#elif DEPTH == 16
+ col = ((uint16_t *)(src1 + pattern_x))[0];
+ pattern_x = (pattern_x + 2) & 15;
+#elif DEPTH == 24
+ {
+ const uint8_t *src2 = src1 + pattern_x * 3;
+ col = src2[0] | (src2[1] << 8) | (src2[2] << 16);
+ pattern_x = (pattern_x + 1) & 7;
+ }
+#else
+ col = ((uint32_t *)(src1 + pattern_x))[0];
+ pattern_x = (pattern_x + 4) & 31;
+#endif
+ PUTPIXEL();
+ d += (DEPTH / 8);
+ }
+ pattern_y = (pattern_y + 1) & 7;
+ dst += dstpitch;
+ }
+}
+
+/* NOTE: srcpitch is ignored */
+static void
+glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
+ (CirrusVGAState * s, uint8_t * dst,
+ const uint8_t * src,
+ int dstpitch, int srcpitch,
+ int bltwidth, int bltheight)
+{
+ uint8_t *d;
+ int x, y;
+ unsigned bits, bits_xor;
+ unsigned int col;
+ unsigned bitmask;
+ unsigned index;
+#if DEPTH == 24
+ int dstskipleft = s->vga.gr[0x2f] & 0x1f;
+ int srcskipleft = dstskipleft / 3;
+#else
+ int srcskipleft = s->vga.gr[0x2f] & 0x07;
+ int dstskipleft = srcskipleft * (DEPTH / 8);
+#endif
+
+ if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
+ bits_xor = 0xff;
+ col = s->cirrus_blt_bgcol;
+ } else {
+ bits_xor = 0x00;
+ col = s->cirrus_blt_fgcol;
+ }
+
+ for(y = 0; y < bltheight; y++) {
+ bitmask = 0x80 >> srcskipleft;
+ bits = *src++ ^ bits_xor;
+ d = dst + dstskipleft;
+ for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+ if ((bitmask & 0xff) == 0) {
+ bitmask = 0x80;
+ bits = *src++ ^ bits_xor;
+ }
+ index = (bits & bitmask);
+ if (index) {
+ PUTPIXEL();
+ }
+ d += (DEPTH / 8);
+ bitmask >>= 1;
+ }
+ dst += dstpitch;
+ }
+}
+
+static void
+glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
+ (CirrusVGAState * s, uint8_t * dst,
+ const uint8_t * src,
+ int dstpitch, int srcpitch,
+ int bltwidth, int bltheight)
+{
+ uint32_t colors[2];
+ uint8_t *d;
+ int x, y;
+ unsigned bits;
+ unsigned int col;
+ unsigned bitmask;
+ int srcskipleft = s->vga.gr[0x2f] & 0x07;
+ int dstskipleft = srcskipleft * (DEPTH / 8);
+
+ colors[0] = s->cirrus_blt_bgcol;
+ colors[1] = s->cirrus_blt_fgcol;
+ for(y = 0; y < bltheight; y++) {
+ bitmask = 0x80 >> srcskipleft;
+ bits = *src++;
+ d = dst + dstskipleft;
+ for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+ if ((bitmask & 0xff) == 0) {
+ bitmask = 0x80;
+ bits = *src++;
+ }
+ col = colors[!!(bits & bitmask)];
+ PUTPIXEL();
+ d += (DEPTH / 8);
+ bitmask >>= 1;
+ }
+ dst += dstpitch;
+ }
+}
+
+static void
+glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
+ (CirrusVGAState * s, uint8_t * dst,
+ const uint8_t * src,
+ int dstpitch, int srcpitch,
+ int bltwidth, int bltheight)
+{
+ uint8_t *d;
+ int x, y, bitpos, pattern_y;
+ unsigned int bits, bits_xor;
+ unsigned int col;
+#if DEPTH == 24
+ int dstskipleft = s->vga.gr[0x2f] & 0x1f;
+ int srcskipleft = dstskipleft / 3;
+#else
+ int srcskipleft = s->vga.gr[0x2f] & 0x07;
+ int dstskipleft = srcskipleft * (DEPTH / 8);
+#endif
+
+ if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
+ bits_xor = 0xff;
+ col = s->cirrus_blt_bgcol;
+ } else {
+ bits_xor = 0x00;
+ col = s->cirrus_blt_fgcol;
+ }
+ pattern_y = s->cirrus_blt_srcaddr & 7;
+
+ for(y = 0; y < bltheight; y++) {
+ bits = src[pattern_y] ^ bits_xor;
+ bitpos = 7 - srcskipleft;
+ d = dst + dstskipleft;
+ for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+ if ((bits >> bitpos) & 1) {
+ PUTPIXEL();
+ }
+ d += (DEPTH / 8);
+ bitpos = (bitpos - 1) & 7;
+ }
+ pattern_y = (pattern_y + 1) & 7;
+ dst += dstpitch;
+ }
+}
+
+static void
+glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
+ (CirrusVGAState * s, uint8_t * dst,
+ const uint8_t * src,
+ int dstpitch, int srcpitch,
+ int bltwidth, int bltheight)
+{
+ uint32_t colors[2];
+ uint8_t *d;
+ int x, y, bitpos, pattern_y;
+ unsigned int bits;
+ unsigned int col;
+ int srcskipleft = s->vga.gr[0x2f] & 0x07;
+ int dstskipleft = srcskipleft * (DEPTH / 8);
+
+ colors[0] = s->cirrus_blt_bgcol;
+ colors[1] = s->cirrus_blt_fgcol;
+ pattern_y = s->cirrus_blt_srcaddr & 7;
+
+ for(y = 0; y < bltheight; y++) {
+ bits = src[pattern_y];
+ bitpos = 7 - srcskipleft;
+ d = dst + dstskipleft;
+ for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+ col = colors[(bits >> bitpos) & 1];
+ PUTPIXEL();
+ d += (DEPTH / 8);
+ bitpos = (bitpos - 1) & 7;
+ }
+ pattern_y = (pattern_y + 1) & 7;
+ dst += dstpitch;
+ }
+}
+
+static void
+glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
+ (CirrusVGAState *s,
+ uint8_t *dst, int dst_pitch,
+ int width, int height)
+{
+ uint8_t *d, *d1;
+ uint32_t col;
+ int x, y;
+
+ col = s->cirrus_blt_fgcol;
+
+ d1 = dst;
+ for(y = 0; y < height; y++) {
+ d = d1;
+ for(x = 0; x < width; x += (DEPTH / 8)) {
+ PUTPIXEL();
+ d += (DEPTH / 8);
+ }
+ d1 += dst_pitch;
+ }
+}
+
+#undef DEPTH
+#undef PUTPIXEL
diff --git a/hw/display/cirrus_vga_template.h b/hw/display/cirrus_vga_template.h
new file mode 100644
index 0000000000..3b28280588
--- /dev/null
+++ b/hw/display/cirrus_vga_template.h
@@ -0,0 +1,102 @@
+/*
+ * QEMU Cirrus VGA Emulator templates
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if DEPTH == 8
+#define BPP 1
+#elif DEPTH == 15 || DEPTH == 16
+#define BPP 2
+#elif DEPTH == 32
+#define BPP 4
+#else
+#error unsupported depth
+#endif
+
+static void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1,
+ const uint8_t *src1,
+ int poffset, int w,
+ unsigned int color0,
+ unsigned int color1,
+ unsigned int color_xor)
+{
+ const uint8_t *plane0, *plane1;
+ int x, b0, b1;
+ uint8_t *d;
+
+ d = d1;
+ plane0 = src1;
+ plane1 = src1 + poffset;
+ for (x = 0; x < w; x++) {
+ b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
+ b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
+#if DEPTH == 8
+ switch (b0 | (b1 << 1)) {
+ case 0:
+ break;
+ case 1:
+ d[0] ^= color_xor;
+ break;
+ case 2:
+ d[0] = color0;
+ break;
+ case 3:
+ d[0] = color1;
+ break;
+ }
+#elif DEPTH == 16
+ switch (b0 | (b1 << 1)) {
+ case 0:
+ break;
+ case 1:
+ ((uint16_t *)d)[0] ^= color_xor;
+ break;
+ case 2:
+ ((uint16_t *)d)[0] = color0;
+ break;
+ case 3:
+ ((uint16_t *)d)[0] = color1;
+ break;
+ }
+#elif DEPTH == 32
+ switch (b0 | (b1 << 1)) {
+ case 0:
+ break;
+ case 1:
+ ((uint32_t *)d)[0] ^= color_xor;
+ break;
+ case 2:
+ ((uint32_t *)d)[0] = color0;
+ break;
+ case 3:
+ ((uint32_t *)d)[0] = color1;
+ break;
+ }
+#else
+#error unsupported depth
+#endif
+ d += BPP;
+ }
+}
+
+#undef DEPTH
+#undef BPP
diff --git a/hw/display/framebuffer.c b/hw/display/framebuffer.c
index 7326a98a41..6be31db2b5 100644
--- a/hw/display/framebuffer.c
+++ b/hw/display/framebuffer.c
@@ -19,7 +19,7 @@
#include "hw/hw.h"
#include "ui/console.h"
-#include "hw/framebuffer.h"
+#include "framebuffer.h"
/* Render an image from a shared memory framebuffer. */
diff --git a/hw/display/framebuffer.h b/hw/display/framebuffer.h
new file mode 100644
index 0000000000..6eae035b7d
--- /dev/null
+++ b/hw/display/framebuffer.h
@@ -0,0 +1,25 @@
+#ifndef QEMU_FRAMEBUFFER_H
+#define QEMU_FRAMEBUFFER_H
+
+#include "exec/memory.h"
+
+/* Framebuffer device helper routines. */
+
+typedef void (*drawfn)(void *, uint8_t *, const uint8_t *, int, int);
+
+void framebuffer_update_display(
+ DisplaySurface *ds,
+ MemoryRegion *address_space,
+ hwaddr base,
+ int cols,
+ int rows,
+ int src_width,
+ int dest_row_pitch,
+ int dest_col_pitch,
+ int invalidate,
+ drawfn fn,
+ void *opaque,
+ int *first_row,
+ int *last_row);
+
+#endif
diff --git a/hw/display/milkymist-vgafb.c b/hw/display/milkymist-vgafb.c
index 98762ecd21..3219041c81 100644
--- a/hw/display/milkymist-vgafb.c
+++ b/hw/display/milkymist-vgafb.c
@@ -26,20 +26,20 @@
#include "hw/sysbus.h"
#include "trace.h"
#include "ui/console.h"
-#include "hw/framebuffer.h"
+#include "framebuffer.h"
#include "ui/pixel_ops.h"
#include "qemu/error-report.h"
#define BITS 8
-#include "hw/milkymist-vgafb_template.h"
+#include "milkymist-vgafb_template.h"
#define BITS 15
-#include "hw/milkymist-vgafb_template.h"
+#include "milkymist-vgafb_template.h"
#define BITS 16
-#include "hw/milkymist-vgafb_template.h"
+#include "milkymist-vgafb_template.h"
#define BITS 24
-#include "hw/milkymist-vgafb_template.h"
+#include "milkymist-vgafb_template.h"
#define BITS 32
-#include "hw/milkymist-vgafb_template.h"
+#include "milkymist-vgafb_template.h"
enum {
R_CTRL = 0,
diff --git a/hw/display/milkymist-vgafb_template.h b/hw/display/milkymist-vgafb_template.h
new file mode 100644
index 0000000000..e0036e16cf
--- /dev/null
+++ b/hw/display/milkymist-vgafb_template.h
@@ -0,0 +1,74 @@
+/*
+ * QEMU model of the Milkymist VGA framebuffer.
+ *
+ * Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#if BITS == 8
+#define COPY_PIXEL(to, r, g, b) \
+ do { \
+ *to = rgb_to_pixel8(r, g, b); \
+ to += 1; \
+ } while (0)
+#elif BITS == 15
+#define COPY_PIXEL(to, r, g, b) \
+ do { \
+ *(uint16_t *)to = rgb_to_pixel15(r, g, b); \
+ to += 2; \
+ } while (0)
+#elif BITS == 16
+#define COPY_PIXEL(to, r, g, b) \
+ do { \
+ *(uint16_t *)to = rgb_to_pixel16(r, g, b); \
+ to += 2; \
+ } while (0)
+#elif BITS == 24
+#define COPY_PIXEL(to, r, g, b) \
+ do { \
+ uint32_t tmp = rgb_to_pixel24(r, g, b); \
+ *(to++) = tmp & 0xff; \
+ *(to++) = (tmp >> 8) & 0xff; \
+ *(to++) = (tmp >> 16) & 0xff; \
+ } while (0)
+#elif BITS == 32
+#define COPY_PIXEL(to, r, g, b) \
+ do { \
+ *(uint32_t *)to = rgb_to_pixel32(r, g, b); \
+ to += 4; \
+ } while (0)
+#else
+#error unknown bit depth
+#endif
+
+static void glue(draw_line_, BITS)(void *opaque, uint8_t *d, const uint8_t *s,
+ int width, int deststep)
+{
+ uint16_t rgb565;
+ uint8_t r, g, b;
+
+ while (width--) {
+ memcpy(&rgb565, s, sizeof(rgb565));
+ r = ((rgb565 >> 11) & 0x1f) << 3;
+ g = ((rgb565 >> 5) & 0x3f) << 2;
+ b = ((rgb565 >> 0) & 0x1f) << 3;
+ COPY_PIXEL(d, r, g, b);
+ s += 2;
+ }
+}
+
+#undef BITS
+#undef COPY_PIXEL
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
new file mode 100644
index 0000000000..2fb96f83ae
--- /dev/null
+++ b/hw/display/omap_lcd_template.h
@@ -0,0 +1,175 @@
+/*
+ * QEMU OMAP LCD Emulator templates
+ *
+ * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if DEPTH == 8
+# define BPP 1
+# define PIXEL_TYPE uint8_t
+#elif DEPTH == 15 || DEPTH == 16
+# define BPP 2
+# define PIXEL_TYPE uint16_t
+#elif DEPTH == 32
+# define BPP 4
+# define PIXEL_TYPE uint32_t
+#else
+# error unsupport depth
+#endif
+
+/*
+ * 2-bit colour
+ */
+static void glue(draw_line2_, DEPTH)(void *opaque,
+ uint8_t *d, const uint8_t *s, int width, int deststep)
+{
+ uint16_t *pal = opaque;
+ uint8_t v, r, g, b;
+
+ do {
+ v = ldub_raw((void *) s);
+ r = (pal[v & 3] >> 4) & 0xf0;
+ g = pal[v & 3] & 0xf0;
+ b = (pal[v & 3] << 4) & 0xf0;
+ ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+ d += BPP;
+ v >>= 2;
+ r = (pal[v & 3] >> 4) & 0xf0;
+ g = pal[v & 3] & 0xf0;
+ b = (pal[v & 3] << 4) & 0xf0;
+ ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+ d += BPP;
+ v >>= 2;
+ r = (pal[v & 3] >> 4) & 0xf0;
+ g = pal[v & 3] & 0xf0;
+ b = (pal[v & 3] << 4) & 0xf0;
+ ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+ d += BPP;
+ v >>= 2;
+ r = (pal[v & 3] >> 4) & 0xf0;
+ g = pal[v & 3] & 0xf0;
+ b = (pal[v & 3] << 4) & 0xf0;
+ ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+ d += BPP;
+ s ++;
+ width -= 4;
+ } while (width > 0);
+}
+
+/*
+ * 4-bit colour
+ */
+static void glue(draw_line4_, DEPTH)(void *opaque,
+ uint8_t *d, const uint8_t *s, int width, int deststep)
+{
+ uint16_t *pal = opaque;
+ uint8_t v, r, g, b;
+
+ do {
+ v = ldub_raw((void *) s);
+ r = (pal[v & 0xf] >> 4) & 0xf0;
+ g = pal[v & 0xf] & 0xf0;
+ b = (pal[v & 0xf] << 4) & 0xf0;
+ ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+ d += BPP;
+ v >>= 4;
+ r = (pal[v & 0xf] >> 4) & 0xf0;
+ g = pal[v & 0xf] & 0xf0;
+ b = (pal[v & 0xf] << 4) & 0xf0;
+ ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+ d += BPP;
+ s ++;
+ width -= 2;
+ } while (width > 0);
+}
+
+/*
+ * 8-bit colour
+ */
+static void glue(draw_line8_, DEPTH)(void *opaque,
+ uint8_t *d, const uint8_t *s, int width, int deststep)
+{
+ uint16_t *pal = opaque;
+ uint8_t v, r, g, b;
+
+ do {
+ v = ldub_raw((void *) s);
+ r = (pal[v] >> 4) & 0xf0;
+ g = pal[v] & 0xf0;
+ b = (pal[v] << 4) & 0xf0;
+ ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+ s ++;
+ d += BPP;
+ } while (-- width != 0);
+}
+
+/*
+ * 12-bit colour
+ */
+static void glue(draw_line12_, DEPTH)(void *opaque,
+ uint8_t *d, const uint8_t *s, int width, int deststep)
+{
+ uint16_t v;
+ uint8_t r, g, b;
+
+ do {
+ v = lduw_raw((void *) s);
+ r = (v >> 4) & 0xf0;
+ g = v & 0xf0;
+ b = (v << 4) & 0xf0;
+ ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+ s += 2;
+ d += BPP;
+ } while (-- width != 0);
+}
+
+/*
+ * 16-bit colour
+ */
+static void glue(draw_line16_, DEPTH)(void *opaque,
+ uint8_t *d, const uint8_t *s, int width, int deststep)
+{
+#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
+ memcpy(d, s, width * 2);
+#else
+ uint16_t v;
+ uint8_t r, g, b;
+
+ do {
+ v = lduw_raw((void *) s);
+ r = (v >> 8) & 0xf8;
+ g = (v >> 3) & 0xfc;
+ b = (v << 3) & 0xf8;
+ ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+ s += 2;
+ d += BPP;
+ } while (-- width != 0);
+#endif
+}
+
+#undef DEPTH
+#undef BPP
+#undef PIXEL_TYPE
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
index 4048cc102d..be7e9c0d74 100644
--- a/hw/display/omap_lcdc.c
+++ b/hw/display/omap_lcdc.c
@@ -19,7 +19,7 @@
#include "hw/hw.h"
#include "ui/console.h"
#include "hw/arm/omap.h"
-#include "hw/framebuffer.h"
+#include "framebuffer.h"
#include "ui/pixel_ops.h"
struct omap_lcd_panel_s {
@@ -70,13 +70,13 @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
#define draw_line_func drawfn
#define DEPTH 8
-#include "hw/omap_lcd_template.h"
+#include "omap_lcd_template.h"
#define DEPTH 15
-#include "hw/omap_lcd_template.h"
+#include "omap_lcd_template.h"
#define DEPTH 16
-#include "hw/omap_lcd_template.h"
+#include "omap_lcd_template.h"
#define DEPTH 32
-#include "hw/omap_lcd_template.h"
+#include "omap_lcd_template.h"
static draw_line_func draw_line_table2[33] = {
[0 ... 32] = NULL,
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
index fbef675f9c..295434eded 100644
--- a/hw/display/pl110.c
+++ b/hw/display/pl110.c
@@ -9,7 +9,7 @@
#include "hw/sysbus.h"
#include "ui/console.h"
-#include "hw/framebuffer.h"
+#include "framebuffer.h"
#include "ui/pixel_ops.h"
#define PL110_CR_EN 0x001
@@ -111,15 +111,15 @@ static const unsigned char *idregs[] = {
};
#define BITS 8
-#include "hw/pl110_template.h"
+#include "pl110_template.h"
#define BITS 15
-#include "hw/pl110_template.h"
+#include "pl110_template.h"
#define BITS 16
-#include "hw/pl110_template.h"
+#include "pl110_template.h"
#define BITS 24
-#include "hw/pl110_template.h"
+#include "pl110_template.h"
#define BITS 32
-#include "hw/pl110_template.h"
+#include "pl110_template.h"
static int pl110_enabled(pl110_state *s)
{
diff --git a/hw/display/pl110_template.h b/hw/display/pl110_template.h
new file mode 100644
index 0000000000..e738e4a241
--- /dev/null
+++ b/hw/display/pl110_template.h
@@ -0,0 +1,395 @@
+/*
+ * Arm PrimeCell PL110 Color LCD Controller
+ *
+ * Copyright (c) 2005 CodeSourcery, LLC.
+ * Written by Paul Brook
+ *
+ * This code is licensed under the GNU LGPL
+ *
+ * Framebuffer format conversion routines.
+ */
+
+#ifndef ORDER
+
+#if BITS == 8
+#define COPY_PIXEL(to, from) *(to++) = from
+#elif BITS == 15 || BITS == 16
+#define COPY_PIXEL(to, from) *(uint16_t *)to = from; to += 2;
+#elif BITS == 24
+#define COPY_PIXEL(to, from) \
+ *(to++) = from; *(to++) = (from) >> 8; *(to++) = (from) >> 16
+#elif BITS == 32
+#define COPY_PIXEL(to, from) *(uint32_t *)to = from; to += 4;
+#else
+#error unknown bit depth
+#endif
+
+#undef RGB
+#define BORDER bgr
+#define ORDER 0
+#include "pl110_template.h"
+#define ORDER 1
+#include "pl110_template.h"
+#define ORDER 2
+#include "pl110_template.h"
+#undef BORDER
+#define RGB
+#define BORDER rgb
+#define ORDER 0
+#include "pl110_template.h"
+#define ORDER 1
+#include "pl110_template.h"
+#define ORDER 2
+#include "pl110_template.h"
+#undef BORDER
+
+static drawfn glue(pl110_draw_fn_,BITS)[48] =
+{
+ glue(pl110_draw_line1_lblp_bgr,BITS),
+ glue(pl110_draw_line2_lblp_bgr,BITS),
+ glue(pl110_draw_line4_lblp_bgr,BITS),
+ glue(pl110_draw_line8_lblp_bgr,BITS),
+ glue(pl110_draw_line16_555_lblp_bgr,BITS),
+ glue(pl110_draw_line32_lblp_bgr,BITS),
+ glue(pl110_draw_line16_lblp_bgr,BITS),
+ glue(pl110_draw_line12_lblp_bgr,BITS),
+
+ glue(pl110_draw_line1_bbbp_bgr,BITS),
+ glue(pl110_draw_line2_bbbp_bgr,BITS),
+ glue(pl110_draw_line4_bbbp_bgr,BITS),
+ glue(pl110_draw_line8_bbbp_bgr,BITS),
+ glue(pl110_draw_line16_555_bbbp_bgr,BITS),
+ glue(pl110_draw_line32_bbbp_bgr,BITS),
+ glue(pl110_draw_line16_bbbp_bgr,BITS),
+ glue(pl110_draw_line12_bbbp_bgr,BITS),
+
+ glue(pl110_draw_line1_lbbp_bgr,BITS),
+ glue(pl110_draw_line2_lbbp_bgr,BITS),
+ glue(pl110_draw_line4_lbbp_bgr,BITS),
+ glue(pl110_draw_line8_lbbp_bgr,BITS),
+ glue(pl110_draw_line16_555_lbbp_bgr,BITS),
+ glue(pl110_draw_line32_lbbp_bgr,BITS),
+ glue(pl110_draw_line16_lbbp_bgr,BITS),
+ glue(pl110_draw_line12_lbbp_bgr,BITS),
+
+ glue(pl110_draw_line1_lblp_rgb,BITS),
+ glue(pl110_draw_line2_lblp_rgb,BITS),
+ glue(pl110_draw_line4_lblp_rgb,BITS),
+ glue(pl110_draw_line8_lblp_rgb,BITS),
+ glue(pl110_draw_line16_555_lblp_rgb,BITS),
+ glue(pl110_draw_line32_lblp_rgb,BITS),
+ glue(pl110_draw_line16_lblp_rgb,BITS),
+ glue(pl110_draw_line12_lblp_rgb,BITS),
+
+ glue(pl110_draw_line1_bbbp_rgb,BITS),
+ glue(pl110_draw_line2_bbbp_rgb,BITS),
+ glue(pl110_draw_line4_bbbp_rgb,BITS),
+ glue(pl110_draw_line8_bbbp_rgb,BITS),
+ glue(pl110_draw_line16_555_bbbp_rgb,BITS),
+ glue(pl110_draw_line32_bbbp_rgb,BITS),
+ glue(pl110_draw_line16_bbbp_rgb,BITS),
+ glue(pl110_draw_line12_bbbp_rgb,BITS),
+
+ glue(pl110_draw_line1_lbbp_rgb,BITS),
+ glue(pl110_draw_line2_lbbp_rgb,BITS),
+ glue(pl110_draw_line4_lbbp_rgb,BITS),
+ glue(pl110_draw_line8_lbbp_rgb,BITS),
+ glue(pl110_draw_line16_555_lbbp_rgb,BITS),
+ glue(pl110_draw_line32_lbbp_rgb,BITS),
+ glue(pl110_draw_line16_lbbp_rgb,BITS),
+ glue(pl110_draw_line12_lbbp_rgb,BITS),
+};
+
+#undef BITS
+#undef COPY_PIXEL
+
+#else
+
+#if ORDER == 0
+#define NAME glue(glue(lblp_, BORDER), BITS)
+#ifdef HOST_WORDS_BIGENDIAN
+#define SWAP_WORDS 1
+#endif
+#elif ORDER == 1
+#define NAME glue(glue(bbbp_, BORDER), BITS)
+#ifndef HOST_WORDS_BIGENDIAN
+#define SWAP_WORDS 1
+#endif
+#else
+#define SWAP_PIXELS 1
+#define NAME glue(glue(lbbp_, BORDER), BITS)
+#ifdef HOST_WORDS_BIGENDIAN
+#define SWAP_WORDS 1
+#endif
+#endif
+
+#define FN_2(x, y) FN(x, y) FN(x+1, y)
+#define FN_4(x, y) FN_2(x, y) FN_2(x+2, y)
+#define FN_8(y) FN_4(0, y) FN_4(4, y)
+
+static void glue(pl110_draw_line1_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
+{
+ uint32_t *palette = opaque;
+ uint32_t data;
+ while (width > 0) {
+ data = *(uint32_t *)src;
+#ifdef SWAP_PIXELS
+#define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 7 - (x))) & 1]);
+#else
+#define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x) + y)) & 1]);
+#endif
+#ifdef SWAP_WORDS
+ FN_8(24)
+ FN_8(16)
+ FN_8(8)
+ FN_8(0)
+#else
+ FN_8(0)
+ FN_8(8)
+ FN_8(16)
+ FN_8(24)
+#endif
+#undef FN
+ width -= 32;
+ src += 4;
+ }
+}
+
+static void glue(pl110_draw_line2_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
+{
+ uint32_t *palette = opaque;
+ uint32_t data;
+ while (width > 0) {
+ data = *(uint32_t *)src;
+#ifdef SWAP_PIXELS
+#define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 6 - (x)*2)) & 3]);
+#else
+#define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*2 + y)) & 3]);
+#endif
+#ifdef SWAP_WORDS
+ FN_4(0, 24)
+ FN_4(0, 16)
+ FN_4(0, 8)
+ FN_4(0, 0)
+#else
+ FN_4(0, 0)
+ FN_4(0, 8)
+ FN_4(0, 16)
+ FN_4(0, 24)
+#endif
+#undef FN
+ width -= 16;
+ src += 4;
+ }
+}
+
+static void glue(pl110_draw_line4_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
+{
+ uint32_t *palette = opaque;
+ uint32_t data;
+ while (width > 0) {
+ data = *(uint32_t *)src;
+#ifdef SWAP_PIXELS
+#define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 4 - (x)*4)) & 0xf]);
+#else
+#define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*4 + y)) & 0xf]);
+#endif
+#ifdef SWAP_WORDS
+ FN_2(0, 24)
+ FN_2(0, 16)
+ FN_2(0, 8)
+ FN_2(0, 0)
+#else
+ FN_2(0, 0)
+ FN_2(0, 8)
+ FN_2(0, 16)
+ FN_2(0, 24)
+#endif
+#undef FN
+ width -= 8;
+ src += 4;
+ }
+}
+
+static void glue(pl110_draw_line8_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
+{
+ uint32_t *palette = opaque;
+ uint32_t data;
+ while (width > 0) {
+ data = *(uint32_t *)src;
+#define FN(x) COPY_PIXEL(d, palette[(data >> (x)) & 0xff]);
+#ifdef SWAP_WORDS
+ FN(24)
+ FN(16)
+ FN(8)
+ FN(0)
+#else
+ FN(0)
+ FN(8)
+ FN(16)
+ FN(24)
+#endif
+#undef FN
+ width -= 4;
+ src += 4;
+ }
+}
+
+static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
+{
+ uint32_t data;
+ unsigned int r, g, b;
+ while (width > 0) {
+ data = *(uint32_t *)src;
+#ifdef SWAP_WORDS
+ data = bswap32(data);
+#endif
+#ifdef RGB
+#define LSB r
+#define MSB b
+#else
+#define LSB b
+#define MSB r
+#endif
+#if 0
+ LSB = data & 0x1f;
+ data >>= 5;
+ g = data & 0x3f;
+ data >>= 6;
+ MSB = data & 0x1f;
+ data >>= 5;
+#else
+ LSB = (data & 0x1f) << 3;
+ data >>= 5;
+ g = (data & 0x3f) << 2;
+ data >>= 6;
+ MSB = (data & 0x1f) << 3;
+ data >>= 5;
+#endif
+ COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+ LSB = (data & 0x1f) << 3;
+ data >>= 5;
+ g = (data & 0x3f) << 2;
+ data >>= 6;
+ MSB = (data & 0x1f) << 3;
+ data >>= 5;
+ COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+#undef MSB
+#undef LSB
+ width -= 2;
+ src += 4;
+ }
+}
+
+static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
+{
+ uint32_t data;
+ unsigned int r, g, b;
+ while (width > 0) {
+ data = *(uint32_t *)src;
+#ifdef RGB
+#define LSB r
+#define MSB b
+#else
+#define LSB b
+#define MSB r
+#endif
+#ifndef SWAP_WORDS
+ LSB = data & 0xff;
+ g = (data >> 8) & 0xff;
+ MSB = (data >> 16) & 0xff;
+#else
+ LSB = (data >> 24) & 0xff;
+ g = (data >> 16) & 0xff;
+ MSB = (data >> 8) & 0xff;
+#endif
+ COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+#undef MSB
+#undef LSB
+ width--;
+ src += 4;
+ }
+}
+
+static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
+{
+ /* RGB 555 plus an intensity bit (which we ignore) */
+ uint32_t data;
+ unsigned int r, g, b;
+ while (width > 0) {
+ data = *(uint32_t *)src;
+#ifdef SWAP_WORDS
+ data = bswap32(data);
+#endif
+#ifdef RGB
+#define LSB r
+#define MSB b
+#else
+#define LSB b
+#define MSB r
+#endif
+ LSB = (data & 0x1f) << 3;
+ data >>= 5;
+ g = (data & 0x1f) << 3;
+ data >>= 5;
+ MSB = (data & 0x1f) << 3;
+ data >>= 5;
+ COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+ LSB = (data & 0x1f) << 3;
+ data >>= 5;
+ g = (data & 0x1f) << 3;
+ data >>= 5;
+ MSB = (data & 0x1f) << 3;
+ data >>= 6;
+ COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+#undef MSB
+#undef LSB
+ width -= 2;
+ src += 4;
+ }
+}
+
+static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
+{
+ /* RGB 444 with 4 bits of zeroes at the top of each halfword */
+ uint32_t data;
+ unsigned int r, g, b;
+ while (width > 0) {
+ data = *(uint32_t *)src;
+#ifdef SWAP_WORDS
+ data = bswap32(data);
+#endif
+#ifdef RGB
+#define LSB r
+#define MSB b
+#else
+#define LSB b
+#define MSB r
+#endif
+ LSB = (data & 0xf) << 4;
+ data >>= 4;
+ g = (data & 0xf) << 4;
+ data >>= 4;
+ MSB = (data & 0xf) << 4;
+ data >>= 8;
+ COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+ LSB = (data & 0xf) << 4;
+ data >>= 4;
+ g = (data & 0xf) << 4;
+ data >>= 4;
+ MSB = (data & 0xf) << 4;
+ data >>= 8;
+ COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+#undef MSB
+#undef LSB
+ width -= 2;
+ src += 4;
+ }
+}
+
+#undef SWAP_PIXELS
+#undef NAME
+#undef SWAP_WORDS
+#undef ORDER
+
+#endif
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
index ee59bc2de3..c9bd42e023 100644
--- a/hw/display/pxa2xx_lcd.c
+++ b/hw/display/pxa2xx_lcd.c
@@ -16,7 +16,7 @@
#include "ui/pixel_ops.h"
/* FIXME: For graphic_rotate. Should probably be done in common code. */
#include "sysemu/sysemu.h"
-#include "hw/framebuffer.h"
+#include "framebuffer.h"
struct DMAChannel {
uint32_t branch;
@@ -981,15 +981,15 @@ static const VMStateDescription vmstate_pxa2xx_lcdc = {
};
#define BITS 8
-#include "hw/pxa2xx_template.h"
+#include "pxa2xx_template.h"
#define BITS 15
-#include "hw/pxa2xx_template.h"
+#include "pxa2xx_template.h"
#define BITS 16
-#include "hw/pxa2xx_template.h"
+#include "pxa2xx_template.h"
#define BITS 24
-#include "hw/pxa2xx_template.h"
+#include "pxa2xx_template.h"
#define BITS 32
-#include "hw/pxa2xx_template.h"
+#include "pxa2xx_template.h"
PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
hwaddr base, qemu_irq irq)
diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h
new file mode 100644
index 0000000000..1cbe36cb80
--- /dev/null
+++ b/hw/display/pxa2xx_template.h
@@ -0,0 +1,435 @@
+/*
+ * Intel XScale PXA255/270 LCDC emulation.
+ *
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Written by Andrzej Zaborowski <balrog@zabor.org>
+ *
+ * This code is licensed under the GPLv2.
+ *
+ * Framebuffer format conversion routines.
+ */
+
+# define SKIP_PIXEL(to) to += deststep
+#if BITS == 8
+# define COPY_PIXEL(to, from) *to = from; SKIP_PIXEL(to)
+#elif BITS == 15 || BITS == 16
+# define COPY_PIXEL(to, from) *(uint16_t *) to = from; SKIP_PIXEL(to)
+#elif BITS == 24
+# define COPY_PIXEL(to, from) \
+ *(uint16_t *) to = from; *(to + 2) = (from) >> 16; SKIP_PIXEL(to)
+#elif BITS == 32
+# define COPY_PIXEL(to, from) *(uint32_t *) to = from; SKIP_PIXEL(to)
+#else
+# error unknown bit depth
+#endif
+
+#ifdef HOST_WORDS_BIGENDIAN
+# define SWAP_WORDS 1
+#endif
+
+#define FN_2(x) FN(x + 1) FN(x)
+#define FN_4(x) FN_2(x + 2) FN_2(x)
+
+static void glue(pxa2xx_draw_line2_, BITS)(void *opaque,
+ uint8_t *dest, const uint8_t *src, int width, int deststep)
+{
+ uint32_t *palette = opaque;
+ uint32_t data;
+ while (width > 0) {
+ data = *(uint32_t *) src;
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
+#ifdef SWAP_WORDS
+ FN_4(12)
+ FN_4(8)
+ FN_4(4)
+ FN_4(0)
+#else
+ FN_4(0)
+ FN_4(4)
+ FN_4(8)
+ FN_4(12)
+#endif
+#undef FN
+ width -= 16;
+ src += 4;
+ }
+}
+
+static void glue(pxa2xx_draw_line4_, BITS)(void *opaque,
+ uint8_t *dest, const uint8_t *src, int width, int deststep)
+{
+ uint32_t *palette = opaque;
+ uint32_t data;
+ while (width > 0) {
+ data = *(uint32_t *) src;
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
+#ifdef SWAP_WORDS
+ FN_2(6)
+ FN_2(4)
+ FN_2(2)
+ FN_2(0)
+#else
+ FN_2(0)
+ FN_2(2)
+ FN_2(4)
+ FN_2(6)
+#endif
+#undef FN
+ width -= 8;
+ src += 4;
+ }
+}
+
+static void glue(pxa2xx_draw_line8_, BITS)(void *opaque,
+ uint8_t *dest, const uint8_t *src, int width, int deststep)
+{
+ uint32_t *palette = opaque;
+ uint32_t data;
+ while (width > 0) {
+ data = *(uint32_t *) src;
+#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
+#ifdef SWAP_WORDS
+ FN(24)
+ FN(16)
+ FN(8)
+ FN(0)
+#else
+ FN(0)
+ FN(8)
+ FN(16)
+ FN(24)
+#endif
+#undef FN
+ width -= 4;
+ src += 4;
+ }
+}
+
+static void glue(pxa2xx_draw_line16_, BITS)(void *opaque,
+ uint8_t *dest, const uint8_t *src, int width, int deststep)
+{
+ uint32_t data;
+ unsigned int r, g, b;
+ while (width > 0) {
+ data = *(uint32_t *) src;
+#ifdef SWAP_WORDS
+ data = bswap32(data);
+#endif
+ b = (data & 0x1f) << 3;
+ data >>= 5;
+ g = (data & 0x3f) << 2;
+ data >>= 6;
+ r = (data & 0x1f) << 3;
+ data >>= 5;
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ b = (data & 0x1f) << 3;
+ data >>= 5;
+ g = (data & 0x3f) << 2;
+ data >>= 6;
+ r = (data & 0x1f) << 3;
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ width -= 2;
+ src += 4;
+ }
+}
+
+static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
+ uint8_t *dest, const uint8_t *src, int width, int deststep)
+{
+ uint32_t data;
+ unsigned int r, g, b;
+ while (width > 0) {
+ data = *(uint32_t *) src;
+#ifdef SWAP_WORDS
+ data = bswap32(data);
+#endif
+ b = (data & 0x1f) << 3;
+ data >>= 5;
+ g = (data & 0x1f) << 3;
+ data >>= 5;
+ r = (data & 0x1f) << 3;
+ data >>= 5;
+ if (data & 1)
+ SKIP_PIXEL(dest);
+ else
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ data >>= 1;
+ b = (data & 0x1f) << 3;
+ data >>= 5;
+ g = (data & 0x1f) << 3;
+ data >>= 5;
+ r = (data & 0x1f) << 3;
+ data >>= 5;
+ if (data & 1)
+ SKIP_PIXEL(dest);
+ else
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ width -= 2;
+ src += 4;
+ }
+}
+
+static void glue(pxa2xx_draw_line18_, BITS)(void *opaque,
+ uint8_t *dest, const uint8_t *src, int width, int deststep)
+{
+ uint32_t data;
+ unsigned int r, g, b;
+ while (width > 0) {
+ data = *(uint32_t *) src;
+#ifdef SWAP_WORDS
+ data = bswap32(data);
+#endif
+ b = (data & 0x3f) << 2;
+ data >>= 6;
+ g = (data & 0x3f) << 2;
+ data >>= 6;
+ r = (data & 0x3f) << 2;
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ width -= 1;
+ src += 4;
+ }
+}
+
+/* The wicked packed format */
+static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque,
+ uint8_t *dest, const uint8_t *src, int width, int deststep)
+{
+ uint32_t data[3];
+ unsigned int r, g, b;
+ while (width > 0) {
+ data[0] = *(uint32_t *) src;
+ src += 4;
+ data[1] = *(uint32_t *) src;
+ src += 4;
+ data[2] = *(uint32_t *) src;
+ src += 4;
+#ifdef SWAP_WORDS
+ data[0] = bswap32(data[0]);
+ data[1] = bswap32(data[1]);
+ data[2] = bswap32(data[2]);
+#endif
+ b = (data[0] & 0x3f) << 2;
+ data[0] >>= 6;
+ g = (data[0] & 0x3f) << 2;
+ data[0] >>= 6;
+ r = (data[0] & 0x3f) << 2;
+ data[0] >>= 12;
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ b = (data[0] & 0x3f) << 2;
+ data[0] >>= 6;
+ g = ((data[1] & 0xf) << 4) | (data[0] << 2);
+ data[1] >>= 4;
+ r = (data[1] & 0x3f) << 2;
+ data[1] >>= 12;
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ b = (data[1] & 0x3f) << 2;
+ data[1] >>= 6;
+ g = (data[1] & 0x3f) << 2;
+ data[1] >>= 6;
+ r = ((data[2] & 0x3) << 6) | (data[1] << 2);
+ data[2] >>= 8;
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ b = (data[2] & 0x3f) << 2;
+ data[2] >>= 6;
+ g = (data[2] & 0x3f) << 2;
+ data[2] >>= 6;
+ r = data[2] << 2;
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ width -= 4;
+ }
+}
+
+static void glue(pxa2xx_draw_line19_, BITS)(void *opaque,
+ uint8_t *dest, const uint8_t *src, int width, int deststep)
+{
+ uint32_t data;
+ unsigned int r, g, b;
+ while (width > 0) {
+ data = *(uint32_t *) src;
+#ifdef SWAP_WORDS
+ data = bswap32(data);
+#endif
+ b = (data & 0x3f) << 2;
+ data >>= 6;
+ g = (data & 0x3f) << 2;
+ data >>= 6;
+ r = (data & 0x3f) << 2;
+ data >>= 6;
+ if (data & 1)
+ SKIP_PIXEL(dest);
+ else
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ width -= 1;
+ src += 4;
+ }
+}
+
+/* The wicked packed format */
+static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
+ uint8_t *dest, const uint8_t *src, int width, int deststep)
+{
+ uint32_t data[3];
+ unsigned int r, g, b;
+ while (width > 0) {
+ data[0] = *(uint32_t *) src;
+ src += 4;
+ data[1] = *(uint32_t *) src;
+ src += 4;
+ data[2] = *(uint32_t *) src;
+ src += 4;
+# ifdef SWAP_WORDS
+ data[0] = bswap32(data[0]);
+ data[1] = bswap32(data[1]);
+ data[2] = bswap32(data[2]);
+# endif
+ b = (data[0] & 0x3f) << 2;
+ data[0] >>= 6;
+ g = (data[0] & 0x3f) << 2;
+ data[0] >>= 6;
+ r = (data[0] & 0x3f) << 2;
+ data[0] >>= 6;
+ if (data[0] & 1)
+ SKIP_PIXEL(dest);
+ else
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ data[0] >>= 6;
+ b = (data[0] & 0x3f) << 2;
+ data[0] >>= 6;
+ g = ((data[1] & 0xf) << 4) | (data[0] << 2);
+ data[1] >>= 4;
+ r = (data[1] & 0x3f) << 2;
+ data[1] >>= 6;
+ if (data[1] & 1)
+ SKIP_PIXEL(dest);
+ else
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ data[1] >>= 6;
+ b = (data[1] & 0x3f) << 2;
+ data[1] >>= 6;
+ g = (data[1] & 0x3f) << 2;
+ data[1] >>= 6;
+ r = ((data[2] & 0x3) << 6) | (data[1] << 2);
+ data[2] >>= 2;
+ if (data[2] & 1)
+ SKIP_PIXEL(dest);
+ else
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ data[2] >>= 6;
+ b = (data[2] & 0x3f) << 2;
+ data[2] >>= 6;
+ g = (data[2] & 0x3f) << 2;
+ data[2] >>= 6;
+ r = data[2] << 2;
+ data[2] >>= 6;
+ if (data[2] & 1)
+ SKIP_PIXEL(dest);
+ else
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ width -= 4;
+ }
+}
+
+static void glue(pxa2xx_draw_line24_, BITS)(void *opaque,
+ uint8_t *dest, const uint8_t *src, int width, int deststep)
+{
+ uint32_t data;
+ unsigned int r, g, b;
+ while (width > 0) {
+ data = *(uint32_t *) src;
+#ifdef SWAP_WORDS
+ data = bswap32(data);
+#endif
+ b = data & 0xff;
+ data >>= 8;
+ g = data & 0xff;
+ data >>= 8;
+ r = data & 0xff;
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ width -= 1;
+ src += 4;
+ }
+}
+
+static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque,
+ uint8_t *dest, const uint8_t *src, int width, int deststep)
+{
+ uint32_t data;
+ unsigned int r, g, b;
+ while (width > 0) {
+ data = *(uint32_t *) src;
+#ifdef SWAP_WORDS
+ data = bswap32(data);
+#endif
+ b = (data & 0x7f) << 1;
+ data >>= 7;
+ g = data & 0xff;
+ data >>= 8;
+ r = data & 0xff;
+ data >>= 8;
+ if (data & 1)
+ SKIP_PIXEL(dest);
+ else
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ width -= 1;
+ src += 4;
+ }
+}
+
+static void glue(pxa2xx_draw_line25_, BITS)(void *opaque,
+ uint8_t *dest, const uint8_t *src, int width, int deststep)
+{
+ uint32_t data;
+ unsigned int r, g, b;
+ while (width > 0) {
+ data = *(uint32_t *) src;
+#ifdef SWAP_WORDS
+ data = bswap32(data);
+#endif
+ b = data & 0xff;
+ data >>= 8;
+ g = data & 0xff;
+ data >>= 8;
+ r = data & 0xff;
+ data >>= 8;
+ if (data & 1)
+ SKIP_PIXEL(dest);
+ else
+ COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
+ width -= 1;
+ src += 4;
+ }
+}
+
+/* Overlay planes disabled, no transparency */
+static drawfn glue(pxa2xx_draw_fn_, BITS)[16] =
+{
+ [0 ... 0xf] = NULL,
+ [pxa_lcdc_2bpp] = glue(pxa2xx_draw_line2_, BITS),
+ [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
+ [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
+ [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16_, BITS),
+ [pxa_lcdc_18bpp] = glue(pxa2xx_draw_line18_, BITS),
+ [pxa_lcdc_18pbpp] = glue(pxa2xx_draw_line18p_, BITS),
+ [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24_, BITS),
+};
+
+/* Overlay planes enabled, transparency used */
+static drawfn glue(glue(pxa2xx_draw_fn_, BITS), t)[16] =
+{
+ [0 ... 0xf] = NULL,
+ [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
+ [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
+ [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16t_, BITS),
+ [pxa_lcdc_19bpp] = glue(pxa2xx_draw_line19_, BITS),
+ [pxa_lcdc_19pbpp] = glue(pxa2xx_draw_line19p_, BITS),
+ [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24t_, BITS),
+ [pxa_lcdc_25bpp] = glue(pxa2xx_draw_line25_, BITS),
+};
+
+#undef BITS
+#undef COPY_PIXEL
+#undef SKIP_PIXEL
+
+#ifdef SWAP_WORDS
+# undef SWAP_WORDS
+#endif
diff --git a/hw/display/qxl-logger.c b/hw/display/qxl-logger.c
index 84f9aa1eda..3cd85d9b97 100644
--- a/hw/display/qxl-logger.c
+++ b/hw/display/qxl-logger.c
@@ -20,7 +20,7 @@
*/
#include "qemu/timer.h"
-#include "hw/qxl.h"
+#include "qxl.h"
static const char *qxl_type[] = {
[ QXL_CMD_NOP ] = "nop",
diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
index 8cd9be434d..f511a622c6 100644
--- a/hw/display/qxl-render.c
+++ b/hw/display/qxl-render.c
@@ -19,7 +19,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "hw/qxl.h"
+#include "qxl.h"
static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
{
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index b66b41442a..930b7cf2ad 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -27,7 +27,7 @@
#include "sysemu/sysemu.h"
#include "trace.h"
-#include "hw/qxl.h"
+#include "qxl.h"
/*
* NOTE: SPICE_RING_PROD_ITEM accesses memory on the pci bar and as
diff --git a/hw/display/qxl.h b/hw/display/qxl.h
new file mode 100644
index 0000000000..8e9b0c299e
--- /dev/null
+++ b/hw/display/qxl.h
@@ -0,0 +1,165 @@
+#ifndef HW_QXL_H
+#define HW_QXL_H 1
+
+#include "qemu-common.h"
+
+#include "ui/console.h"
+#include "hw/hw.h"
+#include "hw/pci/pci.h"
+#include "vga_int.h"
+#include "qemu/thread.h"
+
+#include "ui/qemu-spice.h"
+#include "ui/spice-display.h"
+
+enum qxl_mode {
+ QXL_MODE_UNDEFINED,
+ QXL_MODE_VGA,
+ QXL_MODE_COMPAT, /* spice 0.4.x */
+ QXL_MODE_NATIVE,
+};
+
+#ifndef QXL_VRAM64_RANGE_INDEX
+#define QXL_VRAM64_RANGE_INDEX 4
+#endif
+
+#define QXL_UNDEFINED_IO UINT32_MAX
+
+#define QXL_NUM_DIRTY_RECTS 64
+
+typedef struct PCIQXLDevice {
+ PCIDevice pci;
+ SimpleSpiceDisplay ssd;
+ int id;
+ uint32_t debug;
+ uint32_t guestdebug;
+ uint32_t cmdlog;
+
+ uint32_t guest_bug;
+
+ enum qxl_mode mode;
+ uint32_t cmdflags;
+ int generation;
+ uint32_t revision;
+
+ int32_t num_memslots;
+
+ uint32_t current_async;
+ QemuMutex async_lock;
+
+ struct guest_slots {
+ QXLMemSlot slot;
+ void *ptr;
+ uint64_t size;
+ uint64_t delta;
+ uint32_t active;
+ } guest_slots[NUM_MEMSLOTS];
+
+ struct guest_primary {
+ QXLSurfaceCreate surface;
+ uint32_t commands;
+ uint32_t resized;
+ int32_t qxl_stride;
+ uint32_t abs_stride;
+ uint32_t bits_pp;
+ uint32_t bytes_pp;
+ uint8_t *data;
+ } guest_primary;
+
+ struct surfaces {
+ QXLPHYSICAL *cmds;
+ uint32_t count;
+ uint32_t max;
+ } guest_surfaces;
+ QXLPHYSICAL guest_cursor;
+
+ QXLPHYSICAL guest_monitors_config;
+
+ QemuMutex track_lock;
+
+ /* thread signaling */
+ QemuThread main;
+ int pipe[2];
+
+ /* ram pci bar */
+ QXLRam *ram;
+ VGACommonState vga;
+ uint32_t num_free_res;
+ QXLReleaseInfo *last_release;
+ uint32_t last_release_offset;
+ uint32_t oom_running;
+ uint32_t vgamem_size;
+
+ /* rom pci bar */
+ QXLRom shadow_rom;
+ QXLRom *rom;
+ QXLModes *modes;
+ uint32_t rom_size;
+ MemoryRegion rom_bar;
+
+ /* vram pci bar */
+ uint32_t vram_size;
+ MemoryRegion vram_bar;
+ uint32_t vram32_size;
+ MemoryRegion vram32_bar;
+
+ /* io bar */
+ MemoryRegion io_bar;
+
+ /* user-friendly properties (in megabytes) */
+ uint32_t ram_size_mb;
+ uint32_t vram_size_mb;
+ uint32_t vram32_size_mb;
+ uint32_t vgamem_size_mb;
+
+ /* qxl_render_update state */
+ int render_update_cookie_num;
+ int num_dirty_rects;
+ QXLRect dirty[QXL_NUM_DIRTY_RECTS];
+ QEMUBH *update_area_bh;
+} PCIQXLDevice;
+
+#define PANIC_ON(x) if ((x)) { \
+ printf("%s: PANIC %s failed\n", __FUNCTION__, #x); \
+ abort(); \
+}
+
+#define dprint(_qxl, _level, _fmt, ...) \
+ do { \
+ if (_qxl->debug >= _level) { \
+ fprintf(stderr, "qxl-%d: ", _qxl->id); \
+ fprintf(stderr, _fmt, ## __VA_ARGS__); \
+ } \
+ } while (0)
+
+#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V12
+
+/* qxl.c */
+void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
+void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
+ GCC_FMT_ATTR(2, 3);
+
+void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
+ struct QXLRect *area, struct QXLRect *dirty_rects,
+ uint32_t num_dirty_rects,
+ uint32_t clear_dirty_region,
+ qxl_async_io async, QXLCookie *cookie);
+void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
+ uint32_t count);
+void qxl_spice_oom(PCIQXLDevice *qxl);
+void qxl_spice_reset_memslots(PCIQXLDevice *qxl);
+void qxl_spice_reset_image_cache(PCIQXLDevice *qxl);
+void qxl_spice_reset_cursor(PCIQXLDevice *qxl);
+
+/* qxl-logger.c */
+int qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id);
+int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
+
+/* qxl-render.c */
+void qxl_render_resize(PCIQXLDevice *qxl);
+void qxl_render_update(PCIQXLDevice *qxl);
+int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);
+void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie);
+void qxl_render_update_area_bh(void *opaque);
+
+#endif
diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index d9fcead719..6b660ac1c0 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -1171,28 +1171,28 @@ typedef void draw_hwc_line_func(SM501State * s, int crt, uint8_t * palette,
int c_y, uint8_t *d, int width);
#define DEPTH 8
-#include "hw/sm501_template.h"
+#include "sm501_template.h"
#define DEPTH 15
-#include "hw/sm501_template.h"
+#include "sm501_template.h"
#define BGR_FORMAT
#define DEPTH 15
-#include "hw/sm501_template.h"
+#include "sm501_template.h"
#define DEPTH 16
-#include "hw/sm501_template.h"
+#include "sm501_template.h"
#define BGR_FORMAT
#define DEPTH 16
-#include "hw/sm501_template.h"
+#include "sm501_template.h"
#define DEPTH 32
-#include "hw/sm501_template.h"
+#include "sm501_template.h"
#define BGR_FORMAT
#define DEPTH 32
-#include "hw/sm501_template.h"
+#include "sm501_template.h"
static draw_line_func * draw_line8_funcs[] = {
draw_line8_8,
diff --git a/hw/display/sm501_template.h b/hw/display/sm501_template.h
new file mode 100644
index 0000000000..2d4a3d8b48
--- /dev/null
+++ b/hw/display/sm501_template.h
@@ -0,0 +1,145 @@
+/*
+ * Pixel drawing function templates for QEMU SM501 Device
+ *
+ * Copyright (c) 2008 Shin-ichiro KAWASAKI
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if DEPTH == 8
+#define BPP 1
+#define PIXEL_TYPE uint8_t
+#elif DEPTH == 15 || DEPTH == 16
+#define BPP 2
+#define PIXEL_TYPE uint16_t
+#elif DEPTH == 32
+#define BPP 4
+#define PIXEL_TYPE uint32_t
+#else
+#error unsupport depth
+#endif
+
+#ifdef BGR_FORMAT
+#define PIXEL_NAME glue(DEPTH, bgr)
+#else
+#define PIXEL_NAME DEPTH
+#endif /* BGR_FORMAT */
+
+
+static void glue(draw_line8_, PIXEL_NAME)(
+ uint8_t *d, const uint8_t *s, int width, const uint32_t *pal)
+{
+ uint8_t v, r, g, b;
+ do {
+ v = ldub_raw(s);
+ r = (pal[v] >> 16) & 0xff;
+ g = (pal[v] >> 8) & 0xff;
+ b = (pal[v] >> 0) & 0xff;
+ ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+ s ++;
+ d += BPP;
+ } while (-- width != 0);
+}
+
+static void glue(draw_line16_, PIXEL_NAME)(
+ uint8_t *d, const uint8_t *s, int width, const uint32_t *pal)
+{
+ uint16_t rgb565;
+ uint8_t r, g, b;
+
+ do {
+ rgb565 = lduw_raw(s);
+ r = ((rgb565 >> 11) & 0x1f) << 3;
+ g = ((rgb565 >> 5) & 0x3f) << 2;
+ b = ((rgb565 >> 0) & 0x1f) << 3;
+ ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+ s += 2;
+ d += BPP;
+ } while (-- width != 0);
+}
+
+static void glue(draw_line32_, PIXEL_NAME)(
+ uint8_t *d, const uint8_t *s, int width, const uint32_t *pal)
+{
+ uint8_t r, g, b;
+
+ do {
+ ldub_raw(s);
+#if defined(TARGET_WORDS_BIGENDIAN)
+ r = s[1];
+ g = s[2];
+ b = s[3];
+#else
+ b = s[0];
+ g = s[1];
+ r = s[2];
+#endif
+ ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+ s += 4;
+ d += BPP;
+ } while (-- width != 0);
+}
+
+/**
+ * Draw hardware cursor image on the given line.
+ */
+static void glue(draw_hwc_line_, PIXEL_NAME)(SM501State * s, int crt,
+ uint8_t * palette, int c_y, uint8_t *d, int width)
+{
+ int x, i;
+ uint8_t bitset = 0;
+
+ /* get hardware cursor pattern */
+ uint32_t cursor_addr = get_hwc_address(s, crt);
+ assert(0 <= c_y && c_y < SM501_HWC_HEIGHT);
+ cursor_addr += 64 * c_y / 4; /* 4 pixels per byte */
+ cursor_addr += s->base;
+
+ /* get cursor position */
+ x = get_hwc_x(s, crt);
+ d += x * BPP;
+
+ for (i = 0; i < SM501_HWC_WIDTH && x + i < width; i++) {
+ uint8_t v;
+
+ /* get pixel value */
+ if (i % 4 == 0) {
+ bitset = ldub_phys(cursor_addr);
+ cursor_addr++;
+ }
+ v = bitset & 3;
+ bitset >>= 2;
+
+ /* write pixel */
+ if (v) {
+ v--;
+ uint8_t r = palette[v * 3 + 0];
+ uint8_t g = palette[v * 3 + 1];
+ uint8_t b = palette[v * 3 + 2];
+ ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+ }
+ d += BPP;
+ }
+}
+
+#undef DEPTH
+#undef BPP
+#undef PIXEL_TYPE
+#undef PIXEL_NAME
+#undef BGR_FORMAT
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
index 2d5fa89e9b..e252ce945f 100644
--- a/hw/display/tc6393xb.c
+++ b/hw/display/tc6393xb.c
@@ -421,15 +421,15 @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
}
#define BITS 8
-#include "hw/tc6393xb_template.h"
+#include "tc6393xb_template.h"
#define BITS 15
-#include "hw/tc6393xb_template.h"
+#include "tc6393xb_template.h"
#define BITS 16
-#include "hw/tc6393xb_template.h"
+#include "tc6393xb_template.h"
#define BITS 24
-#include "hw/tc6393xb_template.h"
+#include "tc6393xb_template.h"
#define BITS 32
-#include "hw/tc6393xb_template.h"
+#include "tc6393xb_template.h"
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
{
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
new file mode 100644
index 0000000000..154aafd400
--- /dev/null
+++ b/hw/display/tc6393xb_template.h
@@ -0,0 +1,68 @@
+/*
+ * Toshiba TC6393XB I/O Controller.
+ * Found in Sharp Zaurus SL-6000 (tosa) or some
+ * Toshiba e-Series PDAs.
+ *
+ * FB support code. Based on G364 fb emulator
+ *
+ * Copyright (c) 2007 Hervé Poussineau
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if BITS == 8
+# define SET_PIXEL(addr, color) *(uint8_t*)addr = color;
+#elif BITS == 15 || BITS == 16
+# define SET_PIXEL(addr, color) *(uint16_t*)addr = color;
+#elif BITS == 24
+# define SET_PIXEL(addr, color) \
+ addr[0] = color; addr[1] = (color) >> 8; addr[2] = (color) >> 16;
+#elif BITS == 32
+# define SET_PIXEL(addr, color) *(uint32_t*)addr = color;
+#else
+# error unknown bit depth
+#endif
+
+
+static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
+{
+ DisplaySurface *surface = qemu_console_surface(s->con);
+ int i;
+ uint16_t *data_buffer;
+ uint8_t *data_display;
+
+ data_buffer = s->vram_ptr;
+ data_display = surface_data(surface);
+ for(i = 0; i < s->scr_height; i++) {
+#if (BITS == 16)
+ memcpy(data_display, data_buffer, s->scr_width * 2);
+ data_buffer += s->scr_width;
+ data_display += surface_stride(surface);
+#else
+ int j;
+ for (j = 0; j < s->scr_width; j++, data_display += BITS / 8, data_buffer++) {
+ uint16_t color = *data_buffer;
+ uint32_t dest_color = glue(rgb_to_pixel, BITS)(
+ ((color & 0xf800) * 0x108) >> 11,
+ ((color & 0x7e0) * 0x41) >> 9,
+ ((color & 0x1f) * 0x21) >> 2
+ );
+ SET_PIXEL(data_display, dest_color);
+ }
+#endif
+ }
+}
+
+#undef BITS
+#undef SET_PIXEL
diff --git a/hw/display/vga-isa-mm.c b/hw/display/vga-isa-mm.c
index 3b08720cf4..1c50070216 100644
--- a/hw/display/vga-isa-mm.c
+++ b/hw/display/vga-isa-mm.c
@@ -24,7 +24,7 @@
#include "hw/hw.h"
#include "ui/console.h"
#include "hw/i386/pc.h"
-#include "hw/vga_int.h"
+#include "vga_int.h"
#include "ui/pixel_ops.h"
#include "qemu/timer.h"
diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c
index 89d7fa6c3c..90959ebc2c 100644
--- a/hw/display/vga-isa.c
+++ b/hw/display/vga-isa.c
@@ -26,7 +26,7 @@
#include "hw/hw.h"
#include "ui/console.h"
#include "hw/i386/pc.h"
-#include "hw/vga_int.h"
+#include "vga_int.h"
#include "ui/pixel_ops.h"
#include "qemu/timer.h"
#include "hw/loader.h"
diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c
index 05fa9bcb64..a9c69b6ac7 100644
--- a/hw/display/vga-pci.c
+++ b/hw/display/vga-pci.c
@@ -26,7 +26,7 @@
#include "hw/hw.h"
#include "ui/console.h"
#include "hw/pci/pci.h"
-#include "hw/vga_int.h"
+#include "vga_int.h"
#include "ui/pixel_ops.h"
#include "qemu/timer.h"
#include "hw/loader.h"
diff --git a/hw/display/vga.c b/hw/display/vga.c
index dc31fd574c..c1b67bbbf8 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -22,11 +22,11 @@
* THE SOFTWARE.
*/
#include "hw/hw.h"
-#include "hw/vga.h"
+#include "vga.h"
#include "ui/console.h"
#include "hw/i386/pc.h"
#include "hw/pci/pci.h"
-#include "hw/vga_int.h"
+#include "vga_int.h"
#include "ui/pixel_ops.h"
#include "qemu/timer.h"
#include "hw/xen/xen.h"
@@ -986,28 +986,28 @@ typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width);
#define DEPTH 8
-#include "hw/vga_template.h"
+#include "vga_template.h"
#define DEPTH 15
-#include "hw/vga_template.h"
+#include "vga_template.h"
#define BGR_FORMAT
#define DEPTH 15
-#include "hw/vga_template.h"
+#include "vga_template.h"
#define DEPTH 16
-#include "hw/vga_template.h"
+#include "vga_template.h"
#define BGR_FORMAT
#define DEPTH 16
-#include "hw/vga_template.h"
+#include "vga_template.h"
#define DEPTH 32
-#include "hw/vga_template.h"
+#include "vga_template.h"
#define BGR_FORMAT
#define DEPTH 32
-#include "hw/vga_template.h"
+#include "vga_template.h"
static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
{
diff --git a/hw/display/vga.h b/hw/display/vga.h
new file mode 100644
index 0000000000..d917046da6
--- /dev/null
+++ b/hw/display/vga.h
@@ -0,0 +1,159 @@
+/*
+ * linux/include/video/vga.h -- standard VGA chipset interaction
+ *
+ * Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
+ *
+ * Copyright history from vga16fb.c:
+ * Copyright 1999 Ben Pfaff and Petr Vandrovec
+ * Based on VGA info at http://www.osdever.net/FreeVGA/home.htm
+ * Based on VESA framebuffer (c) 1998 Gerd Knorr
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef __linux_video_vga_h__
+#define __linux_video_vga_h__
+
+/* Some of the code below is taken from SVGAlib. The original,
+ unmodified copyright notice for that code is below. */
+/* VGAlib version 1.2 - (c) 1993 Tommy Frandsen */
+/* */
+/* This library is free software; you can redistribute it and/or */
+/* modify it without any restrictions. This library is distributed */
+/* in the hope that it will be useful, but without any warranty. */
+
+/* Multi-chipset support Copyright 1993 Harm Hanemaayer */
+/* partially copyrighted (C) 1993 by Hartmut Schirmer */
+
+/* VGA data register ports */
+#define VGA_CRT_DC 0x3D5 /* CRT Controller Data Register - color emulation */
+#define VGA_CRT_DM 0x3B5 /* CRT Controller Data Register - mono emulation */
+#define VGA_ATT_R 0x3C1 /* Attribute Controller Data Read Register */
+#define VGA_ATT_W 0x3C0 /* Attribute Controller Data Write Register */
+#define VGA_GFX_D 0x3CF /* Graphics Controller Data Register */
+#define VGA_SEQ_D 0x3C5 /* Sequencer Data Register */
+#define VGA_MIS_R 0x3CC /* Misc Output Read Register */
+#define VGA_MIS_W 0x3C2 /* Misc Output Write Register */
+#define VGA_FTC_R 0x3CA /* Feature Control Read Register */
+#define VGA_IS1_RC 0x3DA /* Input Status Register 1 - color emulation */
+#define VGA_IS1_RM 0x3BA /* Input Status Register 1 - mono emulation */
+#define VGA_PEL_D 0x3C9 /* PEL Data Register */
+#define VGA_PEL_MSK 0x3C6 /* PEL mask register */
+
+/* EGA-specific registers */
+#define EGA_GFX_E0 0x3CC /* Graphics enable processor 0 */
+#define EGA_GFX_E1 0x3CA /* Graphics enable processor 1 */
+
+/* VGA index register ports */
+#define VGA_CRT_IC 0x3D4 /* CRT Controller Index - color emulation */
+#define VGA_CRT_IM 0x3B4 /* CRT Controller Index - mono emulation */
+#define VGA_ATT_IW 0x3C0 /* Attribute Controller Index & Data Write Register */
+#define VGA_GFX_I 0x3CE /* Graphics Controller Index */
+#define VGA_SEQ_I 0x3C4 /* Sequencer Index */
+#define VGA_PEL_IW 0x3C8 /* PEL Write Index */
+#define VGA_PEL_IR 0x3C7 /* PEL Read Index */
+
+/* standard VGA indexes max counts */
+#define VGA_CRT_C 0x19 /* Number of CRT Controller Registers */
+#define VGA_ATT_C 0x15 /* Number of Attribute Controller Registers */
+#define VGA_GFX_C 0x09 /* Number of Graphics Controller Registers */
+#define VGA_SEQ_C 0x05 /* Number of Sequencer Registers */
+#define VGA_MIS_C 0x01 /* Number of Misc Output Register */
+
+/* VGA misc register bit masks */
+#define VGA_MIS_COLOR 0x01
+#define VGA_MIS_ENB_MEM_ACCESS 0x02
+#define VGA_MIS_DCLK_28322_720 0x04
+#define VGA_MIS_ENB_PLL_LOAD (0x04 | 0x08)
+#define VGA_MIS_SEL_HIGH_PAGE 0x20
+
+/* VGA CRT controller register indices */
+#define VGA_CRTC_H_TOTAL 0
+#define VGA_CRTC_H_DISP 1
+#define VGA_CRTC_H_BLANK_START 2
+#define VGA_CRTC_H_BLANK_END 3
+#define VGA_CRTC_H_SYNC_START 4
+#define VGA_CRTC_H_SYNC_END 5
+#define VGA_CRTC_V_TOTAL 6
+#define VGA_CRTC_OVERFLOW 7
+#define VGA_CRTC_PRESET_ROW 8
+#define VGA_CRTC_MAX_SCAN 9
+#define VGA_CRTC_CURSOR_START 0x0A
+#define VGA_CRTC_CURSOR_END 0x0B
+#define VGA_CRTC_START_HI 0x0C
+#define VGA_CRTC_START_LO 0x0D
+#define VGA_CRTC_CURSOR_HI 0x0E
+#define VGA_CRTC_CURSOR_LO 0x0F
+#define VGA_CRTC_V_SYNC_START 0x10
+#define VGA_CRTC_V_SYNC_END 0x11
+#define VGA_CRTC_V_DISP_END 0x12
+#define VGA_CRTC_OFFSET 0x13
+#define VGA_CRTC_UNDERLINE 0x14
+#define VGA_CRTC_V_BLANK_START 0x15
+#define VGA_CRTC_V_BLANK_END 0x16
+#define VGA_CRTC_MODE 0x17
+#define VGA_CRTC_LINE_COMPARE 0x18
+#define VGA_CRTC_REGS VGA_CRT_C
+
+/* VGA CRT controller bit masks */
+#define VGA_CR11_LOCK_CR0_CR7 0x80 /* lock writes to CR0 - CR7 */
+#define VGA_CR17_H_V_SIGNALS_ENABLED 0x80
+
+/* VGA attribute controller register indices */
+#define VGA_ATC_PALETTE0 0x00
+#define VGA_ATC_PALETTE1 0x01
+#define VGA_ATC_PALETTE2 0x02
+#define VGA_ATC_PALETTE3 0x03
+#define VGA_ATC_PALETTE4 0x04
+#define VGA_ATC_PALETTE5 0x05
+#define VGA_ATC_PALETTE6 0x06
+#define VGA_ATC_PALETTE7 0x07
+#define VGA_ATC_PALETTE8 0x08
+#define VGA_ATC_PALETTE9 0x09
+#define VGA_ATC_PALETTEA 0x0A
+#define VGA_ATC_PALETTEB 0x0B
+#define VGA_ATC_PALETTEC 0x0C
+#define VGA_ATC_PALETTED 0x0D
+#define VGA_ATC_PALETTEE 0x0E
+#define VGA_ATC_PALETTEF 0x0F
+#define VGA_ATC_MODE 0x10
+#define VGA_ATC_OVERSCAN 0x11
+#define VGA_ATC_PLANE_ENABLE 0x12
+#define VGA_ATC_PEL 0x13
+#define VGA_ATC_COLOR_PAGE 0x14
+
+#define VGA_AR_ENABLE_DISPLAY 0x20
+
+/* VGA sequencer register indices */
+#define VGA_SEQ_RESET 0x00
+#define VGA_SEQ_CLOCK_MODE 0x01
+#define VGA_SEQ_PLANE_WRITE 0x02
+#define VGA_SEQ_CHARACTER_MAP 0x03
+#define VGA_SEQ_MEMORY_MODE 0x04
+
+/* VGA sequencer register bit masks */
+#define VGA_SR01_CHAR_CLK_8DOTS 0x01 /* bit 0: character clocks 8 dots wide are generated */
+#define VGA_SR01_SCREEN_OFF 0x20 /* bit 5: Screen is off */
+#define VGA_SR02_ALL_PLANES 0x0F /* bits 3-0: enable access to all planes */
+#define VGA_SR04_EXT_MEM 0x02 /* bit 1: allows complete mem access to 256K */
+#define VGA_SR04_SEQ_MODE 0x04 /* bit 2: directs system to use a sequential addressing mode */
+#define VGA_SR04_CHN_4M 0x08 /* bit 3: selects modulo 4 addressing for CPU access to display memory */
+
+/* VGA graphics controller register indices */
+#define VGA_GFX_SR_VALUE 0x00
+#define VGA_GFX_SR_ENABLE 0x01
+#define VGA_GFX_COMPARE_VALUE 0x02
+#define VGA_GFX_DATA_ROTATE 0x03
+#define VGA_GFX_PLANE_READ 0x04
+#define VGA_GFX_MODE 0x05
+#define VGA_GFX_MISC 0x06
+#define VGA_GFX_COMPARE_MASK 0x07
+#define VGA_GFX_BIT_MASK 0x08
+
+/* VGA graphics controller bit masks */
+#define VGA_GR06_GRAPHICS_MODE 0x01
+
+#endif /* __linux_video_vga_h__ */
diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
new file mode 100644
index 0000000000..260f7d6948
--- /dev/null
+++ b/hw/display/vga_int.h
@@ -0,0 +1,218 @@
+/*
+ * QEMU internal VGA defines.
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef HW_VGA_INT_H
+#define HW_VGA_INT_H 1
+
+#include <hw/hw.h>
+#include "qapi/error.h"
+#include "exec/memory.h"
+
+#define ST01_V_RETRACE 0x08
+#define ST01_DISP_ENABLE 0x01
+
+#define VBE_DISPI_MAX_XRES 16000
+#define VBE_DISPI_MAX_YRES 12000
+#define VBE_DISPI_MAX_BPP 32
+
+#define VBE_DISPI_INDEX_ID 0x0
+#define VBE_DISPI_INDEX_XRES 0x1
+#define VBE_DISPI_INDEX_YRES 0x2
+#define VBE_DISPI_INDEX_BPP 0x3
+#define VBE_DISPI_INDEX_ENABLE 0x4
+#define VBE_DISPI_INDEX_BANK 0x5
+#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
+#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
+#define VBE_DISPI_INDEX_X_OFFSET 0x8
+#define VBE_DISPI_INDEX_Y_OFFSET 0x9
+#define VBE_DISPI_INDEX_NB 0xa /* size of vbe_regs[] */
+#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa /* read-only, not in vbe_regs */
+
+#define VBE_DISPI_ID0 0xB0C0
+#define VBE_DISPI_ID1 0xB0C1
+#define VBE_DISPI_ID2 0xB0C2
+#define VBE_DISPI_ID3 0xB0C3
+#define VBE_DISPI_ID4 0xB0C4
+#define VBE_DISPI_ID5 0xB0C5
+
+#define VBE_DISPI_DISABLED 0x00
+#define VBE_DISPI_ENABLED 0x01
+#define VBE_DISPI_GETCAPS 0x02
+#define VBE_DISPI_8BIT_DAC 0x20
+#define VBE_DISPI_LFB_ENABLED 0x40
+#define VBE_DISPI_NOCLEARMEM 0x80
+
+#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000
+
+#define CH_ATTR_SIZE (160 * 100)
+#define VGA_MAX_HEIGHT 2048
+
+struct vga_precise_retrace {
+ int64_t ticks_per_char;
+ int64_t total_chars;
+ int htotal;
+ int hstart;
+ int hend;
+ int vstart;
+ int vend;
+ int freq;
+};
+
+union vga_retrace {
+ struct vga_precise_retrace precise;
+};
+
+struct VGACommonState;
+typedef uint8_t (* vga_retrace_fn)(struct VGACommonState *s);
+typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s);
+
+typedef struct VGACommonState {
+ MemoryRegion *legacy_address_space;
+ uint8_t *vram_ptr;
+ MemoryRegion vram;
+ MemoryRegion vram_vbe;
+ uint32_t vram_size;
+ uint32_t vram_size_mb; /* property */
+ uint32_t latch;
+ MemoryRegion *chain4_alias;
+ uint8_t sr_index;
+ uint8_t sr[256];
+ uint8_t gr_index;
+ uint8_t gr[256];
+ uint8_t ar_index;
+ uint8_t ar[21];
+ int ar_flip_flop;
+ uint8_t cr_index;
+ uint8_t cr[256]; /* CRT registers */
+ uint8_t msr; /* Misc Output Register */
+ uint8_t fcr; /* Feature Control Register */
+ uint8_t st00; /* status 0 */
+ uint8_t st01; /* status 1 */
+ uint8_t dac_state;
+ uint8_t dac_sub_index;
+ uint8_t dac_read_index;
+ uint8_t dac_write_index;
+ uint8_t dac_cache[3]; /* used when writing */
+ int dac_8bit;
+ uint8_t palette[768];
+ int32_t bank_offset;
+ int (*get_bpp)(struct VGACommonState *s);
+ void (*get_offsets)(struct VGACommonState *s,
+ uint32_t *pline_offset,
+ uint32_t *pstart_addr,
+ uint32_t *pline_compare);
+ void (*get_resolution)(struct VGACommonState *s,
+ int *pwidth,
+ int *pheight);
+ /* bochs vbe state */
+ uint16_t vbe_index;
+ uint16_t vbe_regs[VBE_DISPI_INDEX_NB];
+ uint32_t vbe_start_addr;
+ uint32_t vbe_line_offset;
+ uint32_t vbe_bank_mask;
+ int vbe_mapped;
+ /* display refresh support */
+ QemuConsole *con;
+ uint32_t font_offsets[2];
+ int graphic_mode;
+ uint8_t shift_control;
+ uint8_t double_scan;
+ uint32_t line_offset;
+ uint32_t line_compare;
+ uint32_t start_addr;
+ uint32_t plane_updated;
+ uint32_t last_line_offset;
+ uint8_t last_cw, last_ch;
+ uint32_t last_width, last_height; /* in chars or pixels */
+ uint32_t last_scr_width, last_scr_height; /* in pixels */
+ uint32_t last_depth; /* in bits */
+ uint8_t cursor_start, cursor_end;
+ bool cursor_visible_phase;
+ int64_t cursor_blink_time;
+ uint32_t cursor_offset;
+ unsigned int (*rgb_to_pixel)(unsigned int r,
+ unsigned int g, unsigned b);
+ vga_hw_update_ptr update;
+ vga_hw_invalidate_ptr invalidate;
+ vga_hw_screen_dump_ptr screen_dump;
+ vga_hw_text_update_ptr text_update;
+ bool full_update_text;
+ bool full_update_gfx;
+ /* hardware mouse cursor support */
+ uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32];
+ void (*cursor_invalidate)(struct VGACommonState *s);
+ void (*cursor_draw_line)(struct VGACommonState *s, uint8_t *d, int y);
+ /* tell for each page if it has been updated since the last time */
+ uint32_t last_palette[256];
+ uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */
+ /* retrace */
+ vga_retrace_fn retrace;
+ vga_update_retrace_info_fn update_retrace_info;
+ union vga_retrace retrace_info;
+ uint8_t is_vbe_vmstate;
+} VGACommonState;
+
+static inline int c6_to_8(int v)
+{
+ int b;
+ v &= 0x3f;
+ b = v & 1;
+ return (v << 2) | (b << 1) | b;
+}
+
+void vga_common_init(VGACommonState *s);
+void vga_init(VGACommonState *s, MemoryRegion *address_space,
+ MemoryRegion *address_space_io, bool init_vga_ports);
+MemoryRegion *vga_init_io(VGACommonState *s,
+ const MemoryRegionPortio **vga_ports,
+ const MemoryRegionPortio **vbe_ports);
+void vga_common_reset(VGACommonState *s);
+
+void vga_sync_dirty_bitmap(VGACommonState *s);
+void vga_dirty_log_start(VGACommonState *s);
+void vga_dirty_log_stop(VGACommonState *s);
+
+extern const VMStateDescription vmstate_vga_common;
+uint32_t vga_ioport_read(void *opaque, uint32_t addr);
+void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val);
+uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr);
+void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val);
+void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2);
+void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp);
+
+int vga_ioport_invalid(VGACommonState *s, uint32_t addr);
+
+void vga_init_vbe(VGACommonState *s, MemoryRegion *address_space);
+uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr);
+void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val);
+void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val);
+
+extern const uint8_t sr_mask[8];
+extern const uint8_t gr_mask[16];
+
+#define VGABIOS_FILENAME "vgabios.bin"
+#define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
+
+extern const MemoryRegionOps vga_mem_ops;
+
+#endif
diff --git a/hw/display/vga_template.h b/hw/display/vga_template.h
new file mode 100644
index 0000000000..f6f6a01d84
--- /dev/null
+++ b/hw/display/vga_template.h
@@ -0,0 +1,459 @@
+/*
+ * QEMU VGA Emulator templates
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if DEPTH == 8
+#define BPP 1
+#define PIXEL_TYPE uint8_t
+#elif DEPTH == 15 || DEPTH == 16
+#define BPP 2
+#define PIXEL_TYPE uint16_t
+#elif DEPTH == 32
+#define BPP 4
+#define PIXEL_TYPE uint32_t
+#else
+#error unsupport depth
+#endif
+
+#ifdef BGR_FORMAT
+#define PIXEL_NAME glue(DEPTH, bgr)
+#else
+#define PIXEL_NAME DEPTH
+#endif /* BGR_FORMAT */
+
+#if DEPTH != 15 && !defined(BGR_FORMAT)
+
+static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d,
+ uint32_t font_data,
+ uint32_t xorcol,
+ uint32_t bgcol)
+{
+#if BPP == 1
+ ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
+ ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
+#elif BPP == 2
+ ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
+ ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
+ ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
+ ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
+#else
+ ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
+#endif
+}
+
+static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize,
+ const uint8_t *font_ptr, int h,
+ uint32_t fgcol, uint32_t bgcol)
+{
+ uint32_t font_data, xorcol;
+
+ xorcol = bgcol ^ fgcol;
+ do {
+ font_data = font_ptr[0];
+ glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol);
+ font_ptr += 4;
+ d += linesize;
+ } while (--h);
+}
+
+static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
+ const uint8_t *font_ptr, int h,
+ uint32_t fgcol, uint32_t bgcol)
+{
+ uint32_t font_data, xorcol;
+
+ xorcol = bgcol ^ fgcol;
+ do {
+ font_data = font_ptr[0];
+ glue(vga_draw_glyph_line_, DEPTH)(d,
+ expand4to8[font_data >> 4],
+ xorcol, bgcol);
+ glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP,
+ expand4to8[font_data & 0x0f],
+ xorcol, bgcol);
+ font_ptr += 4;
+ d += linesize;
+ } while (--h);
+}
+
+static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
+ const uint8_t *font_ptr, int h,
+ uint32_t fgcol, uint32_t bgcol, int dup9)
+{
+ uint32_t font_data, xorcol, v;
+
+ xorcol = bgcol ^ fgcol;
+ do {
+ font_data = font_ptr[0];
+#if BPP == 1
+ cpu_to_32wu((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
+ v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
+ cpu_to_32wu(((uint32_t *)d)+1, v);
+ if (dup9)
+ ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
+ else
+ ((uint8_t *)d)[8] = bgcol;
+
+#elif BPP == 2
+ cpu_to_32wu(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
+ cpu_to_32wu(((uint32_t *)d)+1, (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
+ cpu_to_32wu(((uint32_t *)d)+2, (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
+ v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
+ cpu_to_32wu(((uint32_t *)d)+3, v);
+ if (dup9)
+ ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
+ else
+ ((uint16_t *)d)[8] = bgcol;
+#else
+ ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
+ v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
+ ((uint32_t *)d)[7] = v;
+ if (dup9)
+ ((uint32_t *)d)[8] = v;
+ else
+ ((uint32_t *)d)[8] = bgcol;
+#endif
+ font_ptr += 4;
+ d += linesize;
+ } while (--h);
+}
+
+/*
+ * 4 color mode
+ */
+static void glue(vga_draw_line2_, DEPTH)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+ uint32_t plane_mask, *palette, data, v;
+ int x;
+
+ palette = s1->last_palette;
+ plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+ width >>= 3;
+ for(x = 0; x < width; x++) {
+ data = ((uint32_t *)s)[0];
+ data &= plane_mask;
+ v = expand2[GET_PLANE(data, 0)];
+ v |= expand2[GET_PLANE(data, 2)] << 2;
+ ((PIXEL_TYPE *)d)[0] = palette[v >> 12];
+ ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf];
+ ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf];
+ ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf];
+
+ v = expand2[GET_PLANE(data, 1)];
+ v |= expand2[GET_PLANE(data, 3)] << 2;
+ ((PIXEL_TYPE *)d)[4] = palette[v >> 12];
+ ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
+ ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
+ ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
+ d += BPP * 8;
+ s += 4;
+ }
+}
+
+#if BPP == 1
+#define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v)
+#elif BPP == 2
+#define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v)
+#else
+#define PUT_PIXEL2(d, n, v) \
+((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
+#endif
+
+/*
+ * 4 color mode, dup2 horizontal
+ */
+static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+ uint32_t plane_mask, *palette, data, v;
+ int x;
+
+ palette = s1->last_palette;
+ plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+ width >>= 3;
+ for(x = 0; x < width; x++) {
+ data = ((uint32_t *)s)[0];
+ data &= plane_mask;
+ v = expand2[GET_PLANE(data, 0)];
+ v |= expand2[GET_PLANE(data, 2)] << 2;
+ PUT_PIXEL2(d, 0, palette[v >> 12]);
+ PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
+ PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
+ PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
+
+ v = expand2[GET_PLANE(data, 1)];
+ v |= expand2[GET_PLANE(data, 3)] << 2;
+ PUT_PIXEL2(d, 4, palette[v >> 12]);
+ PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
+ PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
+ PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
+ d += BPP * 16;
+ s += 4;
+ }
+}
+
+/*
+ * 16 color mode
+ */
+static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+ uint32_t plane_mask, data, v, *palette;
+ int x;
+
+ palette = s1->last_palette;
+ plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+ width >>= 3;
+ for(x = 0; x < width; x++) {
+ data = ((uint32_t *)s)[0];
+ data &= plane_mask;
+ v = expand4[GET_PLANE(data, 0)];
+ v |= expand4[GET_PLANE(data, 1)] << 1;
+ v |= expand4[GET_PLANE(data, 2)] << 2;
+ v |= expand4[GET_PLANE(data, 3)] << 3;
+ ((PIXEL_TYPE *)d)[0] = palette[v >> 28];
+ ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf];
+ ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf];
+ ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf];
+ ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf];
+ ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
+ ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
+ ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
+ d += BPP * 8;
+ s += 4;
+ }
+}
+
+/*
+ * 16 color mode, dup2 horizontal
+ */
+static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+ uint32_t plane_mask, data, v, *palette;
+ int x;
+
+ palette = s1->last_palette;
+ plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+ width >>= 3;
+ for(x = 0; x < width; x++) {
+ data = ((uint32_t *)s)[0];
+ data &= plane_mask;
+ v = expand4[GET_PLANE(data, 0)];
+ v |= expand4[GET_PLANE(data, 1)] << 1;
+ v |= expand4[GET_PLANE(data, 2)] << 2;
+ v |= expand4[GET_PLANE(data, 3)] << 3;
+ PUT_PIXEL2(d, 0, palette[v >> 28]);
+ PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
+ PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
+ PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
+ PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
+ PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
+ PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
+ PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
+ d += BPP * 16;
+ s += 4;
+ }
+}
+
+/*
+ * 256 color mode, double pixels
+ *
+ * XXX: add plane_mask support (never used in standard VGA modes)
+ */
+static void glue(vga_draw_line8d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+ uint32_t *palette;
+ int x;
+
+ palette = s1->last_palette;
+ width >>= 3;
+ for(x = 0; x < width; x++) {
+ PUT_PIXEL2(d, 0, palette[s[0]]);
+ PUT_PIXEL2(d, 1, palette[s[1]]);
+ PUT_PIXEL2(d, 2, palette[s[2]]);
+ PUT_PIXEL2(d, 3, palette[s[3]]);
+ d += BPP * 8;
+ s += 4;
+ }
+}
+
+/*
+ * standard 256 color mode
+ *
+ * XXX: add plane_mask support (never used in standard VGA modes)
+ */
+static void glue(vga_draw_line8_, DEPTH)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+ uint32_t *palette;
+ int x;
+
+ palette = s1->last_palette;
+ width >>= 3;
+ for(x = 0; x < width; x++) {
+ ((PIXEL_TYPE *)d)[0] = palette[s[0]];
+ ((PIXEL_TYPE *)d)[1] = palette[s[1]];
+ ((PIXEL_TYPE *)d)[2] = palette[s[2]];
+ ((PIXEL_TYPE *)d)[3] = palette[s[3]];
+ ((PIXEL_TYPE *)d)[4] = palette[s[4]];
+ ((PIXEL_TYPE *)d)[5] = palette[s[5]];
+ ((PIXEL_TYPE *)d)[6] = palette[s[6]];
+ ((PIXEL_TYPE *)d)[7] = palette[s[7]];
+ d += BPP * 8;
+ s += 8;
+ }
+}
+
+#endif /* DEPTH != 15 */
+
+
+/* XXX: optimize */
+
+/*
+ * 15 bit color
+ */
+static void glue(vga_draw_line15_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+#if DEPTH == 15 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
+ memcpy(d, s, width * 2);
+#else
+ int w;
+ uint32_t v, r, g, b;
+
+ w = width;
+ do {
+ v = lduw_raw((void *)s);
+ r = (v >> 7) & 0xf8;
+ g = (v >> 2) & 0xf8;
+ b = (v << 3) & 0xf8;
+ ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+ s += 2;
+ d += BPP;
+ } while (--w != 0);
+#endif
+}
+
+/*
+ * 16 bit color
+ */
+static void glue(vga_draw_line16_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
+ memcpy(d, s, width * 2);
+#else
+ int w;
+ uint32_t v, r, g, b;
+
+ w = width;
+ do {
+ v = lduw_raw((void *)s);
+ r = (v >> 8) & 0xf8;
+ g = (v >> 3) & 0xfc;
+ b = (v << 3) & 0xf8;
+ ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+ s += 2;
+ d += BPP;
+ } while (--w != 0);
+#endif
+}
+
+/*
+ * 24 bit color
+ */
+static void glue(vga_draw_line24_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+ int w;
+ uint32_t r, g, b;
+
+ w = width;
+ do {
+#if defined(TARGET_WORDS_BIGENDIAN)
+ r = s[0];
+ g = s[1];
+ b = s[2];
+#else
+ b = s[0];
+ g = s[1];
+ r = s[2];
+#endif
+ ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+ s += 3;
+ d += BPP;
+ } while (--w != 0);
+}
+
+/*
+ * 32 bit color
+ */
+static void glue(vga_draw_line32_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+#if DEPTH == 32 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) && !defined(BGR_FORMAT)
+ memcpy(d, s, width * 4);
+#else
+ int w;
+ uint32_t r, g, b;
+
+ w = width;
+ do {
+#if defined(TARGET_WORDS_BIGENDIAN)
+ r = s[1];
+ g = s[2];
+ b = s[3];
+#else
+ b = s[0];
+ g = s[1];
+ r = s[2];
+#endif
+ ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+ s += 4;
+ d += BPP;
+ } while (--w != 0);
+#endif
+}
+
+#undef PUT_PIXEL2
+#undef DEPTH
+#undef BPP
+#undef PIXEL_TYPE
+#undef PIXEL_NAME
+#undef BGR_FORMAT
diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index 5b9ce8f96b..bcad47a68d 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -31,7 +31,7 @@
#define HW_FILL_ACCEL
#define HW_MOUSE_ACCEL
-#include "hw/vga_int.h"
+#include "vga_int.h"
/* See http://vmware-svga.sf.net/ for some documentation on VMWare SVGA */