--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <signal.h>
+
+#include "qemu-common.h"
+#include "console.h"
+#include "sysemu.h"
+
+#define INTEL_DEBUG(format, args...) \
+ fprintf (stderr, "intel.c:%d:%s " format , __LINE__, __func__, ## args)
+
+#define TileW 128
+#define TileH 8
+#define IntelFbBase 0xd0000000
+#define IntelMMIOAddr 0xfe400000
+#define TilePitch 16
+
+#define REG_DR_DSPASURF 0x7019C
+#define REG_DR_DSPACNTR 0x70180
+
+static int display = 0;
+
+static int fd_mem_ro = -1;
+static int fd_mem_rw = -1;
+static unsigned char *intel_mem = NULL;
+static unsigned char *intel_mmio = NULL;
+
+static inline unsigned int intel_get_reg(unsigned int reg)
+{
+ return *(unsigned int*)(intel_mmio + reg);
+}
+
+static inline unsigned int intel_get_tiled_offset(int x, int y)
+{
+ return 4 * (y * (TilePitch * TileW * TileH) + x * (TileW * TileH));
+}
+
+static inline unsigned int intel_get_offset(DisplayState *ds, int x, int y)
+{
+ return (y * ds->width + x) * 4;
+}
+
+static inline void intel_blit_tile(DisplayState *ds, int x, int y)
+{
+ static const int solid_line[] = {0, 3, 4, 7};
+ static const int dashed_line[] = {1, 2, 5, 6};
+ unsigned int toffset, offset, to, o;
+ unsigned char *buff;
+ int i, j;
+
+ buff = (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
+
+ /* Copy the lines 0-3-4-7 */
+ toffset = intel_get_tiled_offset(x, y);
+ offset = intel_get_offset(ds, x * TileW, y * TileH);
+ for (i = 0; i < 4; i++)
+ {
+ to = toffset + solid_line[i] * TileW * 4;
+ o = offset + solid_line[i] * ds->width * 4;
+ memcpy(&buff[to], &ds->data[o], TileW * 4);
+ }
+
+ /* Copy the lines 1-2-5-6 */
+ toffset = to = intel_get_tiled_offset(x, y);
+ offset = o = intel_get_offset(ds, x * TileW, y * TileH);
+ for (i = 0; i < 4; i++)
+ {
+ to = toffset + dashed_line[i] * TileW * 4;
+ o = offset + dashed_line[i] * ds->width * 4 + 16 * 4;
+ /* copy the odd one */
+ for (j = 0; j < 4 ; j++)
+ {
+ memcpy(&buff[to], &ds->data[o], 16 * 4);
+ to += 16 * 4;
+ o -= 16 * 4;
+ memcpy(&buff[to], &ds->data[o], 16 * 4);
+ to += 16 * 4;
+ o += 48 * 4;
+ }
+ }
+}
+
+static void intel_update_tiled(DisplayState *ds, int x, int y, int w, int h)
+{
+ int i,j;
+
+ x = x / TileW;
+ y = y / TileH;
+ w = w / TileW + 1;
+ h = h / TileH + 1;
+
+ for (i = 0; i < h; i++)
+ for (j = 0; j < w; j++)
+ if ((y + i) < 128 && (x + j) < 10)
+ intel_blit_tile(ds, j + x, i + y);
+}
+
+static void intel_update(DisplayState *ds, int x, int y, int w, int h)
+{
+ if (intel_get_reg(REG_DR_DSPACNTR) & 0xA)
+ intel_update_tiled(ds, x, y, h, w);
+ else
+ {
+ unsigned char *buff = (unsigned char*)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
+ INTEL_DEBUG("change ds->data %p\n", buff);
+ ds->data = buff;
+ }
+}
+
+static void intel_resize(DisplayState *ds, int w, int h)
+{
+
+ ds->linesize = w * 4;
+ ds->width = w;
+ ds->height = h;
+ if (intel_get_reg(REG_DR_DSPASURF) & 0xA)
+ {
+ INTEL_DEBUG("%d,%d tiled mode\n", w, h);
+ ds->data = realloc(ds->data, 1280 * ds->linesize);
+ }
+ else
+ {
+ unsigned char *buff = (unsigned char*)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
+ INTEL_DEBUG("%d,%d linear mode\n", w, h);
+ INTEL_DEBUG("change ds->data %p\n", buff);
+ ds->data = buff;
+ }
+}
+
+static void intel_refresh(DisplayState *ds)
+{
+ vga_hw_update();
+}
+
+static void intel_init_mapping(void)
+{
+ fd_mem_ro = open("/dev/mem", O_RDONLY);
+ if (fd_mem_ro == -1)
+ {
+ perror("open");
+ exit(1);
+ }
+ fd_mem_rw = open("/dev/mem", O_RDWR);
+ if (fd_mem_rw == -1)
+ {
+ perror("open");
+ exit(1);
+ }
+
+ intel_mem = mmap(NULL, 0x10000000, PROT_READ | PROT_WRITE, MAP_SHARED,
+ fd_mem_rw, IntelFbBase);
+ if (intel_mem == MAP_FAILED)
+ {
+ perror("mmap");
+ exit(1);
+ }
+ intel_mmio = mmap(NULL, 1024 * 1024, PROT_READ, MAP_SHARED,
+ fd_mem_ro, IntelMMIOAddr);
+ if (intel_mem == MAP_FAILED)
+ {
+ perror("mmap");
+ exit(1);
+ }
+}
+
+void intel_display_init(DisplayState *ds)
+{
+ INTEL_DEBUG("\n");
+
+ intel_init_mapping();
+
+ ds->dpy_update = intel_update;
+ ds->dpy_resize = intel_resize;
+ ds->dpy_refresh = intel_refresh;
+
+ ds->shared_buf = 0;
+ ds->data = NULL;
+ ds->width = 640;
+ ds->height = 400;
+ ds->linesize = 640 * 4;
+ ds->depth = 32;
+}