--- /dev/null
+diff --git a/vbetool.c b/vbetool.c
+index f6eee59..1a3503b 100644
+--- a/vbetool.c
++++ b/vbetool.c
+@@ -8,6 +8,7 @@ This program is released under the terms of the GNU General Public License,
+ version 2
+ */
+
++#include <pci/config.h>
+ #include <pci/pci.h>
+ #include <assert.h>
+ #include <stdio.h>
+@@ -24,6 +25,8 @@ version 2
+ #include <sys/mman.h>
+
+ #include <libx86.h>
++#include "include/xf86int10.h"
++#include "include/x86emu.h"
+ #include "vbetool.h"
+
+ #define access_ptr_register(reg_frame,reg) (reg_frame -> reg)
+@@ -36,14 +39,132 @@ version 2
+ #define DPMS_STATE_OFF 0x0400
+ #define DPMS_STATE_LOW 0x0800
+
++#define dprintf(arg...)
++//#define dprintf(arg...) printf(arg)
++
++#define dfflush(arg...)
++
+ static struct pci_access *pacc;
+
++static struct pci_dev *vga_pci_dev;
++
++#define __BUILDIO(bwl,bw,type) \
++static inline void out##bwl##_local(unsigned long port, unsigned type value) { __asm__ __volatile__("out" #bwl " %" #bw "0, %w1" : : "a"(value), "Nd"(port)); \
++}\
++static inline unsigned type in##bwl##_local(unsigned long port) { \
++ unsigned type value; \
++ __asm__ __volatile__("in" #bwl " %w1, %" #bw "0" : "=a"(value) : "Nd"(port)); \
++ return value; \
++}\
++
++__BUILDIO(b,b,char)
++__BUILDIO(w,w,short)
++__BUILDIO(l,,int)
++
++
++typedef u32 (*emu_io_handler)(u16 port, int write, int size, u32 val);
++
++static u32 igfx_mmio = 0;
++static u32 igfx_index = 0;
++static u32 igfx_ioport = 0;
++
++u32 emu_io(u16 port, int write, int size, u32 val)
++{
++ dprintf("emu_io: 0x%08x %s%c 0x%04x 0x%08x\n",
++ cnt++,
++ write?"out":"in",
++ size==1?'b':size==2?'w':'l',
++ port,
++ (int)val);
++
++ if ( igfx_ioport && write ) {
++ if ( port == igfx_ioport )
++ {
++ if ((val & 1) && (val < 0x10000))
++ {
++ igfx_index = val;
++ return 0;
++ } else {
++ igfx_index = 0;
++ }
++ }
++ else if ( port == igfx_ioport+4 && igfx_index )
++ {
++ dprintf("Real write: 0x%08x -> (0x%08x + 0x200000 + 0x%08x)/0x%08x\n",
++ val, igfx_mmio, igfx_index & ~3, igfx_mmio + 0x200000 + (igfx_index & ~3));
++ *(volatile unsigned int *)(igfx_mmio + 0x200000 + (igfx_index & ~3)) = val;
++ return 0;
++ }
++ }
++
++ if ( write ) {
++ switch (size) {
++ case 1:
++ outb_local(port, val);
++ break;
++ case 2:
++ outw_local(port, val);
++ break;
++ case 4:
++ outl_local(port, val);
++ break;
++ }
++ return 0;
++ } else {
++ switch (size) {
++ case 1:
++ return inb_local(port);
++ case 2:
++ return inw_local(port);
++ case 4:
++ return inl_local(port);
++ }
++ }
++ return 0;
++}
++
++CARD8
++emu_inb(CARD16 port)
++{
++ return emu_io(port, 0, 1, 0);
++}
++
++CARD16
++emu_inw(CARD16 port)
++{
++ return emu_io(port, 0, 2, 0);
++}
++
++CARD32
++emu_inl(CARD16 port)
++{
++ return emu_io(port, 0, 4, 0);
++}
++
++void
++emu_outb(CARD16 port, CARD8 val)
++{
++ emu_io(port, 1, 1, val);
++}
++
++void
++emu_outw(CARD16 port, CARD16 val)
++{
++ emu_io(port, 1, 2, val);
++}
++
++void emu_outl(CARD16 port, CARD32 val)
++{
++ emu_io(port, 1, 4, val);
++}
++
++
+ int vbetool_init (void) {
+ if (!LRMI_init()) {
+ fprintf(stderr, "Failed to initialise LRMI (Linux Real-Mode Interface).\n");
+ exit(1);
+ }
+-
++
+ iopl(3);
+
+ pacc = pci_alloc();
+@@ -117,8 +238,8 @@ int main(int argc, char *argv[])
+ void *rc;
+ int romfd = open (argv[2], O_RDWR);
+
+- munmap(0xc0000, 64*1024);
+- rc = mmap(0xc0000, 64*1024,
++ munmap((void*)0xc0000, 64*1024);
++ rc = mmap((void*)0xc0000, 64*1024,
+ PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_FIXED|MAP_PRIVATE, romfd, 0);
+ }
+@@ -190,12 +311,90 @@ int do_vbe_service(unsigned int AX, unsigned int BX, reg_frame * regs)
+ return access_ptr_register(regs, ebx);
+ }
+
++
++void show_size(pciaddr_t x)
++{
++ if (!x)
++ return;
++ dprintf(" [size=");
++ if (x < 1024)
++ dprintf("%d", (int) x);
++ else if (x < 1048576)
++ dprintf("%dK", (int)(x / 1024));
++ else if (x < 0x80000000)
++ dprintf("%dM", (int)(x / 1048576));
++ else
++ dprintf(PCIADDR_T_FMT, x);
++ dprintf("]");
++}
++
+ int do_real_post(unsigned pci_device)
+ {
+ int error = 0;
++ int c;
+ struct LRMI_regs r;
+ memset(&r, 0, sizeof(r));
+
++ /* Emulate all IO calls */
++ X86EMU_pioFuncs pioFuncs = {
++ (&emu_inb),
++ (&emu_inw),
++ (&emu_inl),
++ (&emu_outb),
++ (&emu_outw),
++ (&emu_outl)
++ };
++ X86EMU_setupPioFuncs(&pioFuncs);
++
++ struct pci_dev *p = vga_pci_dev;
++ pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES);
++
++ /* Workaround for Intel iGFX bug */
++ if ( p->vendor_id == 0x8086 && p->device_id == 0x2a42 ) {
++ dprintf("Activating Intel workaround\n");
++ /* Set up IO regions the BIOS can access */
++ dprintf("VGA PCI device: 0x%08x\n", pci_device);
++
++ u32 mmiobase = 0;
++ for (c=0; c<6; c++) {
++ pciaddr_t pos = p->base_addr[c];
++ pciaddr_t len = (p->known_fields & PCI_FILL_SIZES) ? p->size[c] : 0;
++ u32 flg = pci_read_long(p, PCI_BASE_ADDRESS_0 + 4*c);
++ if (len) {
++ dprintf("PCI base %d: %s at 0x" PCIADDR_T_FMT,
++ c,
++ flg & PCI_BASE_ADDRESS_SPACE_IO ? "I/O" : "memory",
++ pos);
++ show_size(len);
++ dprintf("\n");
++ if (flg & PCI_BASE_ADDRESS_SPACE_IO) {
++ igfx_ioport = pos;
++ } else if (c == 0 && len == 0x400000) {
++ mmiobase = pos;
++ }
++ }
++ }
++ if (!mmiobase) {
++ fprintf(stderr, "ERROR: No MMIO base\n");
++ exit(1);
++ }
++ int memfd = open("/dev/mem", O_RDWR | O_SYNC);
++ if (memfd < 0) {
++ fprintf(stderr, "ERROR: Could not open /dev/mem: %s\n",
++ strerror(errno));
++ exit(1);
++ }
++ igfx_mmio = (u32)mmap(NULL, 0x400000,
++ PROT_READ | PROT_WRITE,
++ MAP_SHARED, memfd, mmiobase);
++ if (igfx_mmio == (u32)MAP_FAILED) {
++ fprintf(stderr, "ERROR: Could not map iGFX mmio area: %s\n",
++ strerror(errno));
++ exit(1);
++ }
++ dprintf("Intel MMIO mapped at %p\n", igfx_mmio);
++ }
++
+ /* Several machines seem to want the device that they're POSTing in
+ here */
+ r.eax = pci_device;
+@@ -230,6 +429,7 @@ int do_post(void)
+ for (p = pacc->devices; p; p = p->next) {
+ c = pci_read_word(p, PCI_CLASS_DEVICE);
+ if (c == 0x300) {
++ vga_pci_dev = p;
+ pci_id =
+ (p->bus << 8) + (p->dev << 3) +
+ (p->func & 0x7);