summaryrefslogtreecommitdiffstats
path: root/qemu/roms/seabios/vgasrc
diff options
context:
space:
mode:
authorYang Zhang <yang.z.zhang@intel.com>2015-08-28 09:58:54 +0800
committerYang Zhang <yang.z.zhang@intel.com>2015-09-01 12:44:00 +0800
commite44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch)
tree66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/seabios/vgasrc
parent9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff)
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5 Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/seabios/vgasrc')
-rw-r--r--qemu/roms/seabios/vgasrc/Kconfig162
-rw-r--r--qemu/roms/seabios/vgasrc/bochsvga.c446
-rw-r--r--qemu/roms/seabios/vgasrc/bochsvga.h57
-rw-r--r--qemu/roms/seabios/vgasrc/cbvga.c193
-rw-r--r--qemu/roms/seabios/vgasrc/cbvga.h20
-rw-r--r--qemu/roms/seabios/vgasrc/clext.c627
-rw-r--r--qemu/roms/seabios/vgasrc/clext.h20
-rw-r--r--qemu/roms/seabios/vgasrc/geodevga.c433
-rw-r--r--qemu/roms/seabios/vgasrc/geodevga.h89
-rw-r--r--qemu/roms/seabios/vgasrc/stdvga.c479
-rw-r--r--qemu/roms/seabios/vgasrc/stdvga.h111
-rw-r--r--qemu/roms/seabios/vgasrc/stdvgaio.c185
-rw-r--r--qemu/roms/seabios/vgasrc/stdvgamodes.c523
-rw-r--r--qemu/roms/seabios/vgasrc/vbe.c426
-rw-r--r--qemu/roms/seabios/vgasrc/vgabios.c1176
-rw-r--r--qemu/roms/seabios/vgasrc/vgabios.h149
-rw-r--r--qemu/roms/seabios/vgasrc/vgaentry.S147
-rw-r--r--qemu/roms/seabios/vgasrc/vgafb.c702
-rw-r--r--qemu/roms/seabios/vgasrc/vgafonts.c785
-rw-r--r--qemu/roms/seabios/vgasrc/vgahw.h143
-rw-r--r--qemu/roms/seabios/vgasrc/vgainit.c195
-rw-r--r--qemu/roms/seabios/vgasrc/vgalayout.lds.S23
22 files changed, 7091 insertions, 0 deletions
diff --git a/qemu/roms/seabios/vgasrc/Kconfig b/qemu/roms/seabios/vgasrc/Kconfig
new file mode 100644
index 000000000..91d590ae2
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/Kconfig
@@ -0,0 +1,162 @@
+# Kconfig SeaBIOS VGA BIOS configuration
+
+menu "VGA ROM"
+ choice
+ prompt "VGA Hardware Type"
+ default NO_VGABIOS
+
+ config NO_VGABIOS
+ bool "None"
+ help
+ Do not build a VGA BIOS.
+
+ config VGA_STANDARD_VGA
+ depends on QEMU
+ bool "QEMU/Bochs Original IBM 256K VGA"
+ select VGA_STDVGA_PORTS
+ help
+ Build basic VGA BIOS support (pre Super-VGA) for use
+ on emulators.
+
+ config VGA_CIRRUS
+ depends on QEMU
+ bool "QEMU/Bochs Cirrus SVGA"
+ select VGA_STDVGA_PORTS
+ help
+ Build support for Cirrus VGA emulation found on QEMU
+ and Bochs emulators. This is for emulators; it is not
+ intended for use on real Cirrus hardware.
+
+ config VGA_BOCHS
+ depends on QEMU
+ bool "QEMU/Bochs VBE SVGA"
+ select VGA_STDVGA_PORTS
+ help
+ Build support for Bochs DISPI interface (a custom VBE
+ protocol) found on QEMU and Bochs emulators.
+
+ config VGA_GEODEGX2
+ bool "GeodeGX2"
+ select VGA_STDVGA_PORTS
+ help
+ Build support for Geode GX2 vga.
+
+ config VGA_GEODELX
+ bool "GeodeLX"
+ select VGA_STDVGA_PORTS
+ help
+ Build support for Geode LX vga.
+
+ config VGA_COREBOOT
+ depends on COREBOOT
+ bool "coreboot linear framebuffer"
+ select VGA_EMULATE_TEXT
+ help
+ Build support for a vgabios wrapper around video
+ devices initialized using coreboot native vga init.
+
+ endchoice
+
+ choice
+ depends on VGA_GEODEGX2 || VGA_GEODELX
+ prompt "Output Mode"
+ default VGA_OUTPUT_CRT
+
+ config VGA_OUTPUT_CRT
+ bool "CRT"
+ help
+ Use CRT for output.
+
+ config VGA_OUTPUT_PANEL
+ bool "Flat Panel"
+ help
+ Use flat panel for output.
+
+ config VGA_OUTPUT_CRT_PANEL
+ bool "CRT and Flat Panel"
+ help
+ Use CRT and flat panel for output.
+ endchoice
+
+ config BUILD_VGABIOS
+ bool
+ default !NO_VGABIOS
+
+ config VGA_STDVGA_PORTS
+ bool
+ config VGA_EMULATE_TEXT
+ bool
+ help
+ Support emulating text mode features when only a
+ framebuffer is available.
+
+ config VGA_FIXUP_ASM
+ depends on BUILD_VGABIOS
+ bool "Fixup assembler to work with broken emulators"
+ default y
+ help
+ This option will cause the build to attempt to avoid
+ certain x86 machine instructions that are known to confuse
+ some emulators. In particular, it works around
+ deficiencies in the Windows vgabios emulator and the
+ x86emu vgabios emulator (frequently used in Xorg).
+
+ config VGA_ALLOCATE_EXTRA_STACK
+ depends on BUILD_VGABIOS
+ bool "Allocate an internal stack for 16bit interrupt entry point"
+ default y
+ help
+ Attempt to allocate (via BIOS PMM call) an internal stack
+ for the legacy 16bit 0x10 interrupt entry point. This
+ reduces the amount of space on the caller's stack that
+ SeaVGABIOS uses.
+
+ config VGA_EXTRA_STACK_SIZE
+ int
+ default 512
+
+ config VGA_VBE
+ depends on BUILD_VGABIOS
+ bool "Video BIOS Extensions (VBE)"
+ default y
+ help
+ Support VBE.
+
+ config VGA_PCI
+ depends on BUILD_VGABIOS && !VGA_COREBOOT
+ bool "PCI ROM Headers"
+ default y
+ help
+ Build PCI ROM headers so the vga rom can be extracted from
+ a PCI device.
+
+ config OVERRIDE_PCI_ID
+ depends on VGA_PCI
+ bool "Override PCI Vendor and Device IDs"
+ help
+ Specify specific values for the PCI Vendor and Device IDs.
+
+ config VGA_VID
+ depends on VGA_PCI
+ hex
+ prompt "PCI Vendor ID" if OVERRIDE_PCI_ID
+ default 0x1013 if VGA_CIRRUS
+ default 0x1234 if VGA_BOCHS
+ default 0x100b if VGA_GEODEGX2
+ default 0x1022 if VGA_GEODELX
+ default 0x0000
+ help
+ Vendor ID for the PCI ROM
+
+ config VGA_DID
+ depends on VGA_PCI
+ hex
+ prompt "PCI Vendor ID" if OVERRIDE_PCI_ID
+ default 0x00b8 if VGA_CIRRUS
+ default 0x1111 if VGA_BOCHS
+ default 0x0030 if VGA_GEODEGX2
+ default 0x2081 if VGA_GEODELX
+ default 0x0000
+ help
+ Device ID for the PCI ROM
+endmenu
diff --git a/qemu/roms/seabios/vgasrc/bochsvga.c b/qemu/roms/seabios/vgasrc/bochsvga.c
new file mode 100644
index 000000000..aa82fc5a5
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/bochsvga.c
@@ -0,0 +1,446 @@
+// Bochs VGA interface to extended "VBE" modes
+//
+// Copyright (C) 2012 Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2011 Julian Pidancet <julian.pidancet@citrix.com>
+// Copyright (C) 2002 Jeroen Janssen
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "biosvar.h" // GET_GLOBAL
+#include "bochsvga.h" // bochsvga_set_mode
+#include "config.h" // CONFIG_*
+#include "hw/pci.h" // pci_config_readl
+#include "hw/pci_regs.h" // PCI_BASE_ADDRESS_0
+#include "output.h" // dprintf
+#include "std/vbe.h" // VBE_CAPABILITY_8BIT_DAC
+#include "stdvga.h" // VGAREG_SEQU_ADDRESS
+#include "vgabios.h" // struct vbe_modeinfo
+#include "x86.h" // outw
+
+
+/****************************************************************
+ * Mode tables
+ ****************************************************************/
+
+static struct bochsvga_mode
+{
+ u16 mode;
+ struct vgamode_s info;
+} bochsvga_modes[] VAR16 = {
+ /* standard modes */
+ { 0x100, { MM_PACKED, 640, 400, 8, 8, 16, SEG_GRAPH } },
+ { 0x101, { MM_PACKED, 640, 480, 8, 8, 16, SEG_GRAPH } },
+ { 0x102, { MM_PLANAR, 800, 600, 4, 8, 16, SEG_GRAPH } },
+ { 0x103, { MM_PACKED, 800, 600, 8, 8, 16, SEG_GRAPH } },
+ { 0x104, { MM_PLANAR, 1024, 768, 4, 8, 16, SEG_GRAPH } },
+ { 0x105, { MM_PACKED, 1024, 768, 8, 8, 16, SEG_GRAPH } },
+ { 0x106, { MM_PLANAR, 1280, 1024, 4, 8, 16, SEG_GRAPH } },
+ { 0x107, { MM_PACKED, 1280, 1024, 8, 8, 16, SEG_GRAPH } },
+ { 0x10D, { MM_DIRECT, 320, 200, 15, 8, 16, SEG_GRAPH } },
+ { 0x10E, { MM_DIRECT, 320, 200, 16, 8, 16, SEG_GRAPH } },
+ { 0x10F, { MM_DIRECT, 320, 200, 24, 8, 16, SEG_GRAPH } },
+ { 0x110, { MM_DIRECT, 640, 480, 15, 8, 16, SEG_GRAPH } },
+ { 0x111, { MM_DIRECT, 640, 480, 16, 8, 16, SEG_GRAPH } },
+ { 0x112, { MM_DIRECT, 640, 480, 24, 8, 16, SEG_GRAPH } },
+ { 0x113, { MM_DIRECT, 800, 600, 15, 8, 16, SEG_GRAPH } },
+ { 0x114, { MM_DIRECT, 800, 600, 16, 8, 16, SEG_GRAPH } },
+ { 0x115, { MM_DIRECT, 800, 600, 24, 8, 16, SEG_GRAPH } },
+ { 0x116, { MM_DIRECT, 1024, 768, 15, 8, 16, SEG_GRAPH } },
+ { 0x117, { MM_DIRECT, 1024, 768, 16, 8, 16, SEG_GRAPH } },
+ { 0x118, { MM_DIRECT, 1024, 768, 24, 8, 16, SEG_GRAPH } },
+ { 0x119, { MM_DIRECT, 1280, 1024, 15, 8, 16, SEG_GRAPH } },
+ { 0x11A, { MM_DIRECT, 1280, 1024, 16, 8, 16, SEG_GRAPH } },
+ { 0x11B, { MM_DIRECT, 1280, 1024, 24, 8, 16, SEG_GRAPH } },
+ { 0x11C, { MM_PACKED, 1600, 1200, 8, 8, 16, SEG_GRAPH } },
+ { 0x11D, { MM_DIRECT, 1600, 1200, 15, 8, 16, SEG_GRAPH } },
+ { 0x11E, { MM_DIRECT, 1600, 1200, 16, 8, 16, SEG_GRAPH } },
+ { 0x11F, { MM_DIRECT, 1600, 1200, 24, 8, 16, SEG_GRAPH } },
+ /* BOCHS modes */
+ { 0x140, { MM_DIRECT, 320, 200, 32, 8, 16, SEG_GRAPH } },
+ { 0x141, { MM_DIRECT, 640, 400, 32, 8, 16, SEG_GRAPH } },
+ { 0x142, { MM_DIRECT, 640, 480, 32, 8, 16, SEG_GRAPH } },
+ { 0x143, { MM_DIRECT, 800, 600, 32, 8, 16, SEG_GRAPH } },
+ { 0x144, { MM_DIRECT, 1024, 768, 32, 8, 16, SEG_GRAPH } },
+ { 0x145, { MM_DIRECT, 1280, 1024, 32, 8, 16, SEG_GRAPH } },
+ { 0x146, { MM_PACKED, 320, 200, 8, 8, 16, SEG_GRAPH } },
+ { 0x147, { MM_DIRECT, 1600, 1200, 32, 8, 16, SEG_GRAPH } },
+ { 0x148, { MM_PACKED, 1152, 864, 8, 8, 16, SEG_GRAPH } },
+ { 0x149, { MM_DIRECT, 1152, 864, 15, 8, 16, SEG_GRAPH } },
+ { 0x14a, { MM_DIRECT, 1152, 864, 16, 8, 16, SEG_GRAPH } },
+ { 0x14b, { MM_DIRECT, 1152, 864, 24, 8, 16, SEG_GRAPH } },
+ { 0x14c, { MM_DIRECT, 1152, 864, 32, 8, 16, SEG_GRAPH } },
+ { 0x175, { MM_DIRECT, 1280, 768, 16, 8, 16, SEG_GRAPH } },
+ { 0x176, { MM_DIRECT, 1280, 768, 24, 8, 16, SEG_GRAPH } },
+ { 0x177, { MM_DIRECT, 1280, 768, 32, 8, 16, SEG_GRAPH } },
+ { 0x178, { MM_DIRECT, 1280, 800, 16, 8, 16, SEG_GRAPH } },
+ { 0x179, { MM_DIRECT, 1280, 800, 24, 8, 16, SEG_GRAPH } },
+ { 0x17a, { MM_DIRECT, 1280, 800, 32, 8, 16, SEG_GRAPH } },
+ { 0x17b, { MM_DIRECT, 1280, 960, 16, 8, 16, SEG_GRAPH } },
+ { 0x17c, { MM_DIRECT, 1280, 960, 24, 8, 16, SEG_GRAPH } },
+ { 0x17d, { MM_DIRECT, 1280, 960, 32, 8, 16, SEG_GRAPH } },
+ { 0x17e, { MM_DIRECT, 1440, 900, 16, 8, 16, SEG_GRAPH } },
+ { 0x17f, { MM_DIRECT, 1440, 900, 24, 8, 16, SEG_GRAPH } },
+ { 0x180, { MM_DIRECT, 1440, 900, 32, 8, 16, SEG_GRAPH } },
+ { 0x181, { MM_DIRECT, 1400, 1050, 16, 8, 16, SEG_GRAPH } },
+ { 0x182, { MM_DIRECT, 1400, 1050, 24, 8, 16, SEG_GRAPH } },
+ { 0x183, { MM_DIRECT, 1400, 1050, 32, 8, 16, SEG_GRAPH } },
+ { 0x184, { MM_DIRECT, 1680, 1050, 16, 8, 16, SEG_GRAPH } },
+ { 0x185, { MM_DIRECT, 1680, 1050, 24, 8, 16, SEG_GRAPH } },
+ { 0x186, { MM_DIRECT, 1680, 1050, 32, 8, 16, SEG_GRAPH } },
+ { 0x187, { MM_DIRECT, 1920, 1200, 16, 8, 16, SEG_GRAPH } },
+ { 0x188, { MM_DIRECT, 1920, 1200, 24, 8, 16, SEG_GRAPH } },
+ { 0x189, { MM_DIRECT, 1920, 1200, 32, 8, 16, SEG_GRAPH } },
+ { 0x18a, { MM_DIRECT, 2560, 1600, 16, 8, 16, SEG_GRAPH } },
+ { 0x18b, { MM_DIRECT, 2560, 1600, 24, 8, 16, SEG_GRAPH } },
+ { 0x18c, { MM_DIRECT, 2560, 1600, 32, 8, 16, SEG_GRAPH } },
+ { 0x18d, { MM_DIRECT, 1280, 720, 16, 8, 16, SEG_GRAPH } },
+ { 0x18e, { MM_DIRECT, 1280, 720, 24, 8, 16, SEG_GRAPH } },
+ { 0x18f, { MM_DIRECT, 1280, 720, 32, 8, 16, SEG_GRAPH } },
+ { 0x190, { MM_DIRECT, 1920, 1080, 16, 8, 16, SEG_GRAPH } },
+ { 0x191, { MM_DIRECT, 1920, 1080, 24, 8, 16, SEG_GRAPH } },
+ { 0x192, { MM_DIRECT, 1920, 1080, 32, 8, 16, SEG_GRAPH } },
+};
+
+static int dispi_found VAR16 = 0;
+
+static int is_bochsvga_mode(struct vgamode_s *vmode_g)
+{
+ return (vmode_g >= &bochsvga_modes[0].info
+ && vmode_g <= &bochsvga_modes[ARRAY_SIZE(bochsvga_modes)-1].info);
+}
+
+struct vgamode_s *bochsvga_find_mode(int mode)
+{
+ struct bochsvga_mode *m = bochsvga_modes;
+ if (GET_GLOBAL(dispi_found))
+ for (; m < &bochsvga_modes[ARRAY_SIZE(bochsvga_modes)]; m++)
+ if (GET_GLOBAL(m->mode) == mode)
+ return &m->info;
+ return stdvga_find_mode(mode);
+}
+
+void
+bochsvga_list_modes(u16 seg, u16 *dest, u16 *last)
+{
+ struct bochsvga_mode *m = bochsvga_modes;
+ if (GET_GLOBAL(dispi_found)) {
+ for (; m < &bochsvga_modes[ARRAY_SIZE(bochsvga_modes)] && dest<last; m++) {
+ u16 mode = GET_GLOBAL(m->mode);
+ if (mode == 0xffff)
+ continue;
+ SET_FARVAR(seg, *dest, mode);
+ dest++;
+ }
+ }
+ stdvga_list_modes(seg, dest, last);
+}
+
+
+/****************************************************************
+ * Helper functions
+ ****************************************************************/
+
+static inline u16 dispi_read(u16 reg)
+{
+ outw(reg, VBE_DISPI_IOPORT_INDEX);
+ return inw(VBE_DISPI_IOPORT_DATA);
+}
+static inline void dispi_write(u16 reg, u16 val)
+{
+ outw(reg, VBE_DISPI_IOPORT_INDEX);
+ outw(val, VBE_DISPI_IOPORT_DATA);
+}
+
+static u8
+bochsvga_dispi_enabled(void)
+{
+ if (!GET_GLOBAL(dispi_found))
+ return 0;
+ u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
+ if (!(en & VBE_DISPI_ENABLED))
+ return 0;
+ return 1;
+}
+
+int
+bochsvga_get_window(struct vgamode_s *vmode_g, int window)
+{
+ if (!bochsvga_dispi_enabled())
+ return stdvga_get_window(vmode_g, window);
+ if (window != 0)
+ return -1;
+ return dispi_read(VBE_DISPI_INDEX_BANK);
+}
+
+int
+bochsvga_set_window(struct vgamode_s *vmode_g, int window, int val)
+{
+ if (!bochsvga_dispi_enabled())
+ return stdvga_set_window(vmode_g, window, val);
+ if (window != 0)
+ return -1;
+ dispi_write(VBE_DISPI_INDEX_BANK, val);
+ if (dispi_read(VBE_DISPI_INDEX_BANK) != val)
+ return -1;
+ return 0;
+}
+
+int
+bochsvga_get_linelength(struct vgamode_s *vmode_g)
+{
+ if (!bochsvga_dispi_enabled())
+ return stdvga_get_linelength(vmode_g);
+ return dispi_read(VBE_DISPI_INDEX_VIRT_WIDTH) * vga_bpp(vmode_g) / 8;
+}
+
+int
+bochsvga_set_linelength(struct vgamode_s *vmode_g, int val)
+{
+ stdvga_set_linelength(vmode_g, val);
+ if (bochsvga_dispi_enabled()) {
+ int pixels = (val * 8) / vga_bpp(vmode_g);
+ dispi_write(VBE_DISPI_INDEX_VIRT_WIDTH, pixels);
+ }
+ return 0;
+}
+
+int
+bochsvga_get_displaystart(struct vgamode_s *vmode_g)
+{
+ if (!bochsvga_dispi_enabled())
+ return stdvga_get_displaystart(vmode_g);
+ int bpp = vga_bpp(vmode_g);
+ int linelength = dispi_read(VBE_DISPI_INDEX_VIRT_WIDTH) * bpp / 8;
+ int x = dispi_read(VBE_DISPI_INDEX_X_OFFSET);
+ int y = dispi_read(VBE_DISPI_INDEX_Y_OFFSET);
+ return x * bpp / 8 + linelength * y;
+}
+
+int
+bochsvga_set_displaystart(struct vgamode_s *vmode_g, int val)
+{
+ stdvga_set_displaystart(vmode_g, val);
+ if (bochsvga_dispi_enabled()) {
+ int bpp = vga_bpp(vmode_g);
+ int linelength = dispi_read(VBE_DISPI_INDEX_VIRT_WIDTH) * bpp / 8;
+ if (!linelength)
+ return 0;
+ dispi_write(VBE_DISPI_INDEX_X_OFFSET, (val % linelength) * 8 / bpp);
+ dispi_write(VBE_DISPI_INDEX_Y_OFFSET, val / linelength);
+ }
+ return 0;
+}
+
+int
+bochsvga_get_dacformat(struct vgamode_s *vmode_g)
+{
+ if (!bochsvga_dispi_enabled())
+ return stdvga_get_dacformat(vmode_g);
+ u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
+ return (en & VBE_DISPI_8BIT_DAC) ? 8 : 6;
+}
+
+int
+bochsvga_set_dacformat(struct vgamode_s *vmode_g, int val)
+{
+ if (!bochsvga_dispi_enabled())
+ return stdvga_set_dacformat(vmode_g, val);
+ u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
+ if (val == 6)
+ en &= ~VBE_DISPI_8BIT_DAC;
+ else if (val == 8)
+ en |= VBE_DISPI_8BIT_DAC;
+ else
+ return -1;
+ dispi_write(VBE_DISPI_INDEX_ENABLE, en);
+ return 0;
+}
+
+static int
+bochsvga_save_state(u16 seg, u16 *info)
+{
+ u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
+ SET_FARVAR(seg, *info, en);
+ info++;
+ if (!(en & VBE_DISPI_ENABLED))
+ return 0;
+ int i;
+ for (i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++)
+ if (i != VBE_DISPI_INDEX_ENABLE) {
+ u16 v = dispi_read(i);
+ SET_FARVAR(seg, *info, v);
+ info++;
+ }
+ return 0;
+}
+
+static int
+bochsvga_restore_state(u16 seg, u16 *info)
+{
+ u16 en = GET_FARVAR(seg, *info);
+ info++;
+ if (!(en & VBE_DISPI_ENABLED)) {
+ dispi_write(VBE_DISPI_INDEX_ENABLE, en);
+ return 0;
+ }
+ int i;
+ for (i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++)
+ if (i == VBE_DISPI_INDEX_ENABLE) {
+ dispi_write(i, en);
+ } else {
+ dispi_write(i, GET_FARVAR(seg, *info));
+ info++;
+ }
+ return 0;
+}
+
+int
+bochsvga_save_restore(int cmd, u16 seg, void *data)
+{
+ int ret = stdvga_save_restore(cmd, seg, data);
+ if (ret < 0 || !(cmd & SR_REGISTERS) || !GET_GLOBAL(dispi_found))
+ return ret;
+
+ u16 *info = (data + ret);
+ if (cmd & SR_SAVE)
+ bochsvga_save_state(seg, info);
+ if (cmd & SR_RESTORE)
+ bochsvga_restore_state(seg, info);
+ return ret + (VBE_DISPI_INDEX_Y_OFFSET-VBE_DISPI_INDEX_XRES+1)*sizeof(u16);
+}
+
+
+/****************************************************************
+ * Mode setting
+ ****************************************************************/
+
+int
+bochsvga_set_mode(struct vgamode_s *vmode_g, int flags)
+{
+ if (GET_GLOBAL(dispi_found))
+ dispi_write(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
+ if (! is_bochsvga_mode(vmode_g))
+ return stdvga_set_mode(vmode_g, flags);
+ if (!GET_GLOBAL(dispi_found))
+ return -1;
+
+ u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
+ if (memmodel == MM_PLANAR)
+ stdvga_set_mode(stdvga_find_mode(0x6a), 0);
+ if (memmodel == MM_PACKED && !(flags & MF_NOPALETTE))
+ stdvga_set_packed_palette();
+
+ dispi_write(VBE_DISPI_INDEX_BPP, GET_GLOBAL(vmode_g->depth));
+ u16 width = GET_GLOBAL(vmode_g->width);
+ u16 height = GET_GLOBAL(vmode_g->height);
+ dispi_write(VBE_DISPI_INDEX_XRES, width);
+ dispi_write(VBE_DISPI_INDEX_YRES, height);
+ dispi_write(VBE_DISPI_INDEX_BANK, 0);
+ u16 bf = ((flags & MF_NOCLEARMEM ? VBE_DISPI_NOCLEARMEM : 0)
+ | (flags & MF_LINEARFB ? VBE_DISPI_LFB_ENABLED : 0));
+ dispi_write(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | bf);
+
+ /* VGA compat setup */
+ u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS;
+ stdvga_crtc_write(crtc_addr, 0x11, 0x00);
+ stdvga_crtc_write(crtc_addr, 0x01, width / 8 - 1);
+ stdvga_set_linelength(vmode_g, width);
+ stdvga_crtc_write(crtc_addr, 0x12, height - 1);
+ u8 v = 0;
+ if ((height - 1) & 0x0100)
+ v |= 0x02;
+ if ((height - 1) & 0x0200)
+ v |= 0x40;
+ stdvga_crtc_mask(crtc_addr, 0x07, 0x42, v);
+
+ stdvga_crtc_write(crtc_addr, 0x09, 0x00);
+ stdvga_crtc_mask(crtc_addr, 0x17, 0x00, 0x03);
+ stdvga_attr_mask(0x10, 0x00, 0x01);
+ stdvga_grdc_write(0x06, 0x05);
+ stdvga_sequ_write(0x02, 0x0f);
+ if (memmodel != MM_PLANAR) {
+ stdvga_crtc_mask(crtc_addr, 0x14, 0x00, 0x40);
+ stdvga_attr_mask(0x10, 0x00, 0x40);
+ stdvga_sequ_mask(0x04, 0x00, 0x08);
+ stdvga_grdc_mask(0x05, 0x20, 0x40);
+ }
+ stdvga_attrindex_write(0x20);
+
+ return 0;
+}
+
+
+/****************************************************************
+ * Init
+ ****************************************************************/
+
+int
+bochsvga_setup(void)
+{
+ int ret = stdvga_setup();
+ if (ret)
+ return ret;
+
+ /* Sanity checks */
+ dispi_write(VBE_DISPI_INDEX_ID, VBE_DISPI_ID0);
+ if (dispi_read(VBE_DISPI_INDEX_ID) != VBE_DISPI_ID0) {
+ dprintf(1, "No VBE DISPI interface detected, falling back to stdvga\n");
+ return 0;
+ }
+
+ dispi_write(VBE_DISPI_INDEX_ID, VBE_DISPI_ID5);
+ SET_VGA(dispi_found, 1);
+
+ if (GET_GLOBAL(HaveRunInit))
+ return 0;
+
+ u32 lfb_addr = VBE_DISPI_LFB_PHYSICAL_ADDRESS;
+ int bdf = GET_GLOBAL(VgaBDF);
+ if (CONFIG_VGA_PCI && bdf >= 0) {
+ u16 vendor = pci_config_readw(bdf, PCI_VENDOR_ID);
+ int barid;
+ switch (vendor) {
+ case 0x15ad: /* qemu vmware vga */
+ barid = 1;
+ break;
+ default: /* stdvga, qxl, virtio */
+ barid = 0;
+ break;
+ }
+ u32 bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_0 + barid * 4);
+ lfb_addr = bar & PCI_BASE_ADDRESS_MEM_MASK;
+ dprintf(1, "VBE DISPI: bdf %02x:%02x.%x, bar %d\n", pci_bdf_to_bus(bdf)
+ , pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf), barid);
+ }
+
+ SET_VGA(VBE_framebuffer, lfb_addr);
+ u32 totalmem = dispi_read(VBE_DISPI_INDEX_VIDEO_MEMORY_64K) * 64 * 1024;
+ SET_VGA(VBE_total_memory, totalmem);
+ SET_VGA(VBE_win_granularity, 64);
+ SET_VGA(VBE_capabilities, VBE_CAPABILITY_8BIT_DAC);
+
+ dprintf(1, "VBE DISPI: lfb_addr=%x, size %d MB\n",
+ lfb_addr, totalmem >> 20);
+
+ // Validate modes
+ u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
+ dispi_write(VBE_DISPI_INDEX_ENABLE, en | VBE_DISPI_GETCAPS);
+ u16 max_xres = dispi_read(VBE_DISPI_INDEX_XRES);
+ u16 max_bpp = dispi_read(VBE_DISPI_INDEX_BPP);
+ dispi_write(VBE_DISPI_INDEX_ENABLE, en);
+ struct bochsvga_mode *m = bochsvga_modes;
+ for (; m < &bochsvga_modes[ARRAY_SIZE(bochsvga_modes)]; m++) {
+ u16 width = GET_GLOBAL(m->info.width);
+ u16 height = GET_GLOBAL(m->info.height);
+ u8 depth = GET_GLOBAL(m->info.depth);
+ u32 mem = (height * DIV_ROUND_UP(width * vga_bpp(&m->info), 8)
+ * stdvga_vram_ratio(&m->info));
+
+ if (width > max_xres || depth > max_bpp || mem > totalmem) {
+ dprintf(1, "Removing mode %x\n", GET_GLOBAL(m->mode));
+ SET_VGA(m->mode, 0xffff);
+ }
+ }
+
+ return 0;
+}
diff --git a/qemu/roms/seabios/vgasrc/bochsvga.h b/qemu/roms/seabios/vgasrc/bochsvga.h
new file mode 100644
index 000000000..ae5f75db2
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/bochsvga.h
@@ -0,0 +1,57 @@
+#ifndef __BOCHSVGA_H
+#define __BOCHSVGA_H
+
+#include "types.h" // u8
+
+#define VBE_DISPI_BANK_ADDRESS 0xA0000
+#define VBE_DISPI_BANK_SIZE_KB 64
+
+#define VBE_DISPI_MAX_XRES 2560
+#define VBE_DISPI_MAX_YRES 1600
+
+#define VBE_DISPI_IOPORT_INDEX 0x01CE
+#define VBE_DISPI_IOPORT_DATA 0x01CF
+
+#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_VIDEO_MEMORY_64K 0xa
+
+#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
+
+struct vgamode_s *bochsvga_find_mode(int mode);
+void bochsvga_list_modes(u16 seg, u16 *dest, u16 *last);
+int bochsvga_get_window(struct vgamode_s *vmode_g, int window);
+int bochsvga_set_window(struct vgamode_s *vmode_g, int window, int val);
+int bochsvga_get_linelength(struct vgamode_s *vmode_g);
+int bochsvga_set_linelength(struct vgamode_s *vmode_g, int val);
+int bochsvga_get_displaystart(struct vgamode_s *vmode_g);
+int bochsvga_set_displaystart(struct vgamode_s *vmode_g, int val);
+int bochsvga_get_dacformat(struct vgamode_s *vmode_g);
+int bochsvga_set_dacformat(struct vgamode_s *vmode_g, int val);
+int bochsvga_save_restore(int cmd, u16 seg, void *data);
+int bochsvga_set_mode(struct vgamode_s *vmode_g, int flags);
+int bochsvga_setup(void);
+
+#endif // bochsvga.h
diff --git a/qemu/roms/seabios/vgasrc/cbvga.c b/qemu/roms/seabios/vgasrc/cbvga.c
new file mode 100644
index 000000000..1cfb9d377
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/cbvga.c
@@ -0,0 +1,193 @@
+// Simple framebuffer vgabios for use with coreboot native vga init.
+//
+// Copyright (C) 2014 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "biosvar.h" // GET_BDA
+#include "cbvga.h" // cbvga_setup
+#include "output.h" // dprintf
+#include "stdvga.h" // SEG_CTEXT
+#include "string.h" // memset16_far
+#include "util.h" // find_cb_table
+#include "vgabios.h" // VGAREG_*
+
+static int CBmode VAR16;
+static struct vgamode_s CBmodeinfo VAR16;
+static struct vgamode_s CBemulinfo VAR16;
+static u32 CBlinelength VAR16;
+
+struct vgamode_s *cbvga_find_mode(int mode)
+{
+ if (mode == GET_GLOBAL(CBmode))
+ return &CBmodeinfo;
+ if (mode == 0x03)
+ return &CBemulinfo;
+ return NULL;
+}
+
+void
+cbvga_list_modes(u16 seg, u16 *dest, u16 *last)
+{
+ if (dest<last) {
+ SET_FARVAR(seg, *dest, GET_GLOBAL(CBmode));
+ dest++;
+ }
+ SET_FARVAR(seg, *dest, 0xffff);
+}
+
+int
+cbvga_get_window(struct vgamode_s *vmode_g, int window)
+{
+ return -1;
+}
+
+int
+cbvga_set_window(struct vgamode_s *vmode_g, int window, int val)
+{
+ return -1;
+}
+
+int
+cbvga_get_linelength(struct vgamode_s *vmode_g)
+{
+ return GET_GLOBAL(CBlinelength);
+}
+
+int
+cbvga_set_linelength(struct vgamode_s *vmode_g, int val)
+{
+ return -1;
+}
+
+int
+cbvga_get_displaystart(struct vgamode_s *vmode_g)
+{
+ return 0;
+}
+
+int
+cbvga_set_displaystart(struct vgamode_s *vmode_g, int val)
+{
+ return -1;
+}
+
+int
+cbvga_get_dacformat(struct vgamode_s *vmode_g)
+{
+ return -1;
+}
+
+int
+cbvga_set_dacformat(struct vgamode_s *vmode_g, int val)
+{
+ return -1;
+}
+
+int
+cbvga_save_restore(int cmd, u16 seg, void *data)
+{
+ if (cmd & (SR_HARDWARE|SR_DAC|SR_REGISTERS))
+ return -1;
+ return bda_save_restore(cmd, seg, data);
+}
+
+int
+cbvga_set_mode(struct vgamode_s *vmode_g, int flags)
+{
+ u8 emul = vmode_g == &CBemulinfo || GET_GLOBAL(CBmode) == 0x03;
+ MASK_BDA_EXT(flags, BF_EMULATE_TEXT, emul ? BF_EMULATE_TEXT : 0);
+ if (!(flags & MF_NOCLEARMEM)) {
+ if (GET_GLOBAL(CBmodeinfo.memmodel) == MM_TEXT) {
+ memset16_far(SEG_CTEXT, (void*)0, 0x0720, 80*25*2);
+ return 0;
+ }
+ struct gfx_op op;
+ init_gfx_op(&op, vmode_g);
+ op.x = op.y = 0;
+ op.xlen = GET_GLOBAL(CBmodeinfo.width);
+ op.ylen = GET_GLOBAL(CBmodeinfo.height);
+ op.op = GO_MEMSET;
+ handle_gfx_op(&op);
+ }
+ return 0;
+}
+
+#define CB_TAG_FRAMEBUFFER 0x0012
+struct cb_framebuffer {
+ u32 tag;
+ u32 size;
+
+ u64 physical_address;
+ u32 x_resolution;
+ u32 y_resolution;
+ u32 bytes_per_line;
+ u8 bits_per_pixel;
+ u8 red_mask_pos;
+ u8 red_mask_size;
+ u8 green_mask_pos;
+ u8 green_mask_size;
+ u8 blue_mask_pos;
+ u8 blue_mask_size;
+ u8 reserved_mask_pos;
+ u8 reserved_mask_size;
+};
+
+int
+cbvga_setup(void)
+{
+ dprintf(1, "coreboot vga init\n");
+
+ if (GET_GLOBAL(HaveRunInit))
+ return 0;
+
+ struct cb_header *cbh = find_cb_table();
+ if (!cbh) {
+ dprintf(1, "Unable to find coreboot table\n");
+ return -1;
+ }
+ struct cb_framebuffer *cbfb = find_cb_subtable(cbh, CB_TAG_FRAMEBUFFER);
+ if (!cbfb) {
+ // Assume there is an EGA text framebuffer.
+ dprintf(1, "Did not find coreboot framebuffer - assuming EGA text\n");
+ SET_VGA(CBmode, 0x03);
+ SET_VGA(CBlinelength, 80*2);
+ SET_VGA(CBmodeinfo.memmodel, MM_TEXT);
+ SET_VGA(CBmodeinfo.width, 80);
+ SET_VGA(CBmodeinfo.height, 25);
+ SET_VGA(CBmodeinfo.depth, 4);
+ SET_VGA(CBmodeinfo.cwidth, 9);
+ SET_VGA(CBmodeinfo.cheight, 16);
+ SET_VGA(CBmodeinfo.sstart, SEG_CTEXT);
+ return 0;
+ }
+
+ u64 addr = GET_FARVAR(0, cbfb->physical_address);
+ u8 bpp = GET_FARVAR(0, cbfb->bits_per_pixel);
+ u32 xlines = GET_FARVAR(0, cbfb->x_resolution);
+ u32 ylines = GET_FARVAR(0, cbfb->y_resolution);
+ u32 linelength = GET_FARVAR(0, cbfb->bytes_per_line);
+ dprintf(1, "Found FB @ %llx %dx%d with %d bpp (%d stride)\n"
+ , addr, xlines, ylines, bpp, linelength);
+
+ if (!addr || addr > 0xffffffff
+ || (bpp != 15 && bpp != 16 && bpp != 24 && bpp != 32)) {
+ dprintf(1, "Unable to use FB\n");
+ return -1;
+ }
+
+ SET_VGA(CBmode, 0x140);
+ SET_VGA(VBE_framebuffer, addr);
+ SET_VGA(VBE_total_memory, linelength * ylines);
+ SET_VGA(CBlinelength, linelength);
+ SET_VGA(CBmodeinfo.memmodel, MM_DIRECT);
+ SET_VGA(CBmodeinfo.width, xlines);
+ SET_VGA(CBmodeinfo.height, ylines);
+ SET_VGA(CBmodeinfo.depth, bpp);
+ SET_VGA(CBmodeinfo.cwidth, 8);
+ SET_VGA(CBmodeinfo.cheight, 16);
+ memcpy_far(get_global_seg(), &CBemulinfo
+ , get_global_seg(), &CBmodeinfo, sizeof(CBemulinfo));
+
+ return 0;
+}
diff --git a/qemu/roms/seabios/vgasrc/cbvga.h b/qemu/roms/seabios/vgasrc/cbvga.h
new file mode 100644
index 000000000..fb892c85b
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/cbvga.h
@@ -0,0 +1,20 @@
+#ifndef __CBVGA_H
+#define __CBVGA_H
+
+#include "types.h" // u16
+
+struct vgamode_s *cbvga_find_mode(int mode);
+void cbvga_list_modes(u16 seg, u16 *dest, u16 *last);
+int cbvga_get_window(struct vgamode_s *vmode_g, int window);
+int cbvga_set_window(struct vgamode_s *vmode_g, int window, int val);
+int cbvga_get_linelength(struct vgamode_s *vmode_g);
+int cbvga_set_linelength(struct vgamode_s *vmode_g, int val);
+int cbvga_get_displaystart(struct vgamode_s *vmode_g);
+int cbvga_set_displaystart(struct vgamode_s *vmode_g, int val);
+int cbvga_get_dacformat(struct vgamode_s *vmode_g);
+int cbvga_set_dacformat(struct vgamode_s *vmode_g, int val);
+int cbvga_save_restore(int cmd, u16 seg, void *data);
+int cbvga_set_mode(struct vgamode_s *vmode_g, int flags);
+int cbvga_setup(void);
+
+#endif // cbvga.h
diff --git a/qemu/roms/seabios/vgasrc/clext.c b/qemu/roms/seabios/vgasrc/clext.c
new file mode 100644
index 000000000..fc5b42f62
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/clext.c
@@ -0,0 +1,627 @@
+// QEMU Cirrus CLGD 54xx VGABIOS Extension.
+//
+// Copyright (C) 2009 Kevin O'Connor <kevin@koconnor.net>
+// Copyright (c) 2004 Makoto Suzuki (suzu)
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "biosvar.h" // GET_GLOBAL
+#include "bregs.h" // struct bregs
+#include "clext.h" // clext_setup
+#include "hw/pci.h" // pci_config_readl
+#include "hw/pci_regs.h" // PCI_BASE_ADDRESS_0
+#include "output.h" // dprintf
+#include "stdvga.h" // VGAREG_SEQU_ADDRESS
+#include "string.h" // memset16_far
+#include "vgabios.h" // VBE_VENDOR_STRING
+
+
+/****************************************************************
+ * Cirrus mode tables
+ ****************************************************************/
+
+/* VGA */
+static u16 cseq_vga[] VAR16 = {0x0007,0xffff};
+static u16 cgraph_vga[] VAR16 = {0x0009,0x000a,0x000b,0xffff};
+static u16 ccrtc_vga[] VAR16 = {0x001a,0x001b,0x001d,0xffff};
+
+/* extensions */
+static u16 cgraph_svgacolor[] VAR16 = {
+ 0x0000,0x0001,0x0002,0x0003,0x0004,0x4005,0x0506,0x0f07,0xff08,
+ 0x0009,0x000a,0x000b,
+ 0xffff
+};
+/* 640x480x8 */
+static u16 cseq_640x480x8[] VAR16 = {
+ 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
+ 0x580b,0x580c,0x580d,0x580e,
+ 0x0412,0x0013,0x2017,
+ 0x331b,0x331c,0x331d,0x331e,
+ 0xffff
+};
+static u16 ccrtc_640x480x8[] VAR16 = {
+ 0x2c11,
+ 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
+ 0x4009,0x000c,0x000d,
+ 0xea10,0xdf12,0x5013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
+ 0x001a,0x221b,0x001d,
+ 0xffff
+};
+/* 640x480x16 */
+static u16 cseq_640x480x16[] VAR16 = {
+ 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
+ 0x580b,0x580c,0x580d,0x580e,
+ 0x0412,0x0013,0x2017,
+ 0x331b,0x331c,0x331d,0x331e,
+ 0xffff
+};
+static u16 ccrtc_640x480x16[] VAR16 = {
+ 0x2c11,
+ 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
+ 0x4009,0x000c,0x000d,
+ 0xea10,0xdf12,0xa013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
+ 0x001a,0x221b,0x001d,
+ 0xffff
+};
+/* 640x480x24 */
+static u16 cseq_640x480x24[] VAR16 = {
+ 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
+ 0x580b,0x580c,0x580d,0x580e,
+ 0x0412,0x0013,0x2017,
+ 0x331b,0x331c,0x331d,0x331e,
+ 0xffff
+};
+static u16 ccrtc_640x480x24[] VAR16 = {
+ 0x2c11,
+ 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,
+ 0x4009,0x000c,0x000d,
+ 0xea10,0xdf12,0xf013,0x4014,0xdf15,0x0b16,0xc317,0xff18,
+ 0x001a,0x221b,0x001d,
+ 0xffff
+};
+/* 800x600x8 */
+static u16 cseq_800x600x8[] VAR16 = {
+ 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
+ 0x230b,0x230c,0x230d,0x230e,
+ 0x0412,0x0013,0x2017,
+ 0x141b,0x141c,0x141d,0x141e,
+ 0xffff
+};
+static u16 ccrtc_800x600x8[] VAR16 = {
+ 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
+ 0x6009,0x000c,0x000d,
+ 0x7d10,0x5712,0x6413,0x4014,0x5715,0x9816,0xc317,0xff18,
+ 0x001a,0x221b,0x001d,
+ 0xffff
+};
+/* 800x600x16 */
+static u16 cseq_800x600x16[] VAR16 = {
+ 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
+ 0x230b,0x230c,0x230d,0x230e,
+ 0x0412,0x0013,0x2017,
+ 0x141b,0x141c,0x141d,0x141e,
+ 0xffff
+};
+static u16 ccrtc_800x600x16[] VAR16 = {
+ 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
+ 0x6009,0x000c,0x000d,
+ 0x7d10,0x5712,0xc813,0x4014,0x5715,0x9816,0xc317,0xff18,
+ 0x001a,0x221b,0x001d,
+ 0xffff
+};
+/* 800x600x24 */
+static u16 cseq_800x600x24[] VAR16 = {
+ 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
+ 0x230b,0x230c,0x230d,0x230e,
+ 0x0412,0x0013,0x2017,
+ 0x141b,0x141c,0x141d,0x141e,
+ 0xffff
+};
+static u16 ccrtc_800x600x24[] VAR16 = {
+ 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,
+ 0x6009,0x000c,0x000d,
+ 0x7d10,0x5712,0x2c13,0x4014,0x5715,0x9816,0xc317,0xff18,
+ 0x001a,0x321b,0x001d,
+ 0xffff
+};
+/* 1024x768x8 */
+static u16 cseq_1024x768x8[] VAR16 = {
+ 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
+ 0x760b,0x760c,0x760d,0x760e,
+ 0x0412,0x0013,0x2017,
+ 0x341b,0x341c,0x341d,0x341e,
+ 0xffff
+};
+static u16 ccrtc_1024x768x8[] VAR16 = {
+ 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
+ 0x6009,0x000c,0x000d,
+ 0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,
+ 0x001a,0x221b,0x001d,
+ 0xffff
+};
+/* 1024x768x16 */
+static u16 cseq_1024x768x16[] VAR16 = {
+ 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
+ 0x760b,0x760c,0x760d,0x760e,
+ 0x0412,0x0013,0x2017,
+ 0x341b,0x341c,0x341d,0x341e,
+ 0xffff
+};
+static u16 ccrtc_1024x768x16[] VAR16 = {
+ 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
+ 0x6009,0x000c,0x000d,
+ 0x0310,0xff12,0x0013,0x4014,0xff15,0x2416,0xc317,0xff18,
+ 0x001a,0x321b,0x001d,
+ 0xffff
+};
+/* 1024x768x24 */
+static u16 cseq_1024x768x24[] VAR16 = {
+ 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,
+ 0x760b,0x760c,0x760d,0x760e,
+ 0x0412,0x0013,0x2017,
+ 0x341b,0x341c,0x341d,0x341e,
+ 0xffff
+};
+static u16 ccrtc_1024x768x24[] VAR16 = {
+ 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,
+ 0x6009,0x000c,0x000d,
+ 0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,
+ 0x001a,0x321b,0x001d,
+ 0xffff
+};
+/* 1280x1024x8 */
+static u16 cseq_1280x1024x8[] VAR16 = {
+ 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
+ 0x760b,0x760c,0x760d,0x760e,
+ 0x0412,0x0013,0x2017,
+ 0x341b,0x341c,0x341d,0x341e,
+ 0xffff
+};
+static u16 ccrtc_1280x1024x8[] VAR16 = {
+ 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
+ 0x6009,0x000c,0x000d,
+ 0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18,
+ 0x001a,0x221b,0x001d,
+ 0xffff
+};
+/* 1280x1024x16 */
+static u16 cseq_1280x1024x16[] VAR16 = {
+ 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,
+ 0x760b,0x760c,0x760d,0x760e,
+ 0x0412,0x0013,0x2017,
+ 0x341b,0x341c,0x341d,0x341e,
+ 0xffff
+};
+static u16 ccrtc_1280x1024x16[] VAR16 = {
+ 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
+ 0x6009,0x000c,0x000d,
+ 0x0310,0xff12,0x4013,0x4014,0xff15,0x2416,0xc317,0xff18,
+ 0x001a,0x321b,0x001d,
+ 0xffff
+};
+
+/* 1600x1200x8 */
+static u16 cseq_1600x1200x8[] VAR16 = {
+ 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,
+ 0x760b,0x760c,0x760d,0x760e,
+ 0x0412,0x0013,0x2017,
+ 0x341b,0x341c,0x341d,0x341e,
+ 0xffff
+};
+static u16 ccrtc_1600x1200x8[] VAR16 = {
+ 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,
+ 0x6009,0x000c,0x000d,
+ 0x0310,0xff12,0xc813,0x4014,0xff15,0x2416,0xc317,0xff18,
+ 0x001a,0x221b,0x001d,
+ 0xffff
+};
+
+struct cirrus_mode_s {
+ u16 mode, vesamode;
+ struct vgamode_s info;
+
+ u16 hidden_dac; /* 0x3c6 */
+ u16 *seq; /* 0x3c4 */
+ u16 *graph; /* 0x3ce */
+ u16 *crtc; /* 0x3d4 */
+};
+
+static struct cirrus_mode_s cirrus_modes[] VAR16 = {
+ {0x5f,0x101,{MM_PACKED,640,480,8,8,16,SEG_GRAPH},0x00,
+ cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8},
+ {0x64,0x111,{MM_DIRECT,640,480,16,8,16,SEG_GRAPH},0xe1,
+ cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16},
+ {0x66,0x110,{MM_DIRECT,640,480,15,8,16,SEG_GRAPH},0xf0,
+ cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16},
+ {0x71,0x112,{MM_DIRECT,640,480,24,8,16,SEG_GRAPH},0xe5,
+ cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24},
+
+ {0x5c,0x103,{MM_PACKED,800,600,8,8,16,SEG_GRAPH},0x00,
+ cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8},
+ {0x65,0x114,{MM_DIRECT,800,600,16,8,16,SEG_GRAPH},0xe1,
+ cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16},
+ {0x67,0x113,{MM_DIRECT,800,600,15,8,16,SEG_GRAPH},0xf0,
+ cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16},
+
+ {0x60,0x105,{MM_PACKED,1024,768,8,8,16,SEG_GRAPH},0x00,
+ cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8},
+ {0x74,0x117,{MM_DIRECT,1024,768,16,8,16,SEG_GRAPH},0xe1,
+ cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16},
+ {0x68,0x116,{MM_DIRECT,1024,768,15,8,16,SEG_GRAPH},0xf0,
+ cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16},
+
+ {0x78,0x115,{MM_DIRECT,800,600,24,8,16,SEG_GRAPH},0xe5,
+ cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24},
+ {0x79,0x118,{MM_DIRECT,1024,768,24,8,16,SEG_GRAPH},0xe5,
+ cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24},
+
+ {0x6d,0x107,{MM_PACKED,1280,1024,8,8,16,SEG_GRAPH},0x00,
+ cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8},
+ {0x69,0x119,{MM_DIRECT,1280,1024,15,8,16,SEG_GRAPH},0xf0,
+ cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16},
+ {0x75,0x11a,{MM_DIRECT,1280,1024,16,8,16,SEG_GRAPH},0xe1,
+ cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16},
+
+ {0x7b,0xffff,{MM_PACKED,1600,1200,8,8,16,SEG_GRAPH},0x00,
+ cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8},
+};
+
+static struct cirrus_mode_s mode_switchback VAR16 =
+ {0xfe,0xffff,{0xff},0,cseq_vga,cgraph_vga,ccrtc_vga};
+
+int
+is_cirrus_mode(struct vgamode_s *vmode_g)
+{
+ return (vmode_g >= &cirrus_modes[0].info
+ && vmode_g <= &cirrus_modes[ARRAY_SIZE(cirrus_modes)-1].info);
+}
+
+struct vgamode_s *
+clext_find_mode(int mode)
+{
+ struct cirrus_mode_s *table_g = cirrus_modes;
+ while (table_g < &cirrus_modes[ARRAY_SIZE(cirrus_modes)]) {
+ if (GET_GLOBAL(table_g->mode) == mode
+ || GET_GLOBAL(table_g->vesamode) == mode)
+ return &table_g->info;
+ table_g++;
+ }
+ return stdvga_find_mode(mode);
+}
+
+void
+clext_list_modes(u16 seg, u16 *dest, u16 *last)
+{
+ int i;
+ for (i=0; i<ARRAY_SIZE(cirrus_modes) && dest<last; i++) {
+ u16 mode = GET_GLOBAL(cirrus_modes[i].vesamode);
+ if (mode == 0xffff)
+ continue;
+ SET_FARVAR(seg, *dest, mode);
+ dest++;
+ }
+ stdvga_list_modes(seg, dest, last);
+}
+
+
+/****************************************************************
+ * helper functions
+ ****************************************************************/
+
+int
+clext_get_window(struct vgamode_s *vmode_g, int window)
+{
+ return stdvga_grdc_read(window + 9);
+}
+
+int
+clext_set_window(struct vgamode_s *vmode_g, int window, int val)
+{
+ if (val >= 0x100)
+ return -1;
+ stdvga_grdc_write(window + 9, val);
+ return 0;
+}
+
+int
+clext_get_linelength(struct vgamode_s *vmode_g)
+{
+ u16 crtc_addr = stdvga_get_crtc();
+ u8 reg13 = stdvga_crtc_read(crtc_addr, 0x13);
+ u8 reg1b = stdvga_crtc_read(crtc_addr, 0x1b);
+ return (((reg1b & 0x10) << 4) + reg13) * 8 / stdvga_vram_ratio(vmode_g);
+}
+
+int
+clext_set_linelength(struct vgamode_s *vmode_g, int val)
+{
+ u16 crtc_addr = stdvga_get_crtc();
+ val = DIV_ROUND_UP(val * stdvga_vram_ratio(vmode_g), 8);
+ stdvga_crtc_write(crtc_addr, 0x13, val);
+ stdvga_crtc_mask(crtc_addr, 0x1b, 0x10, (val & 0x100) >> 4);
+ return 0;
+}
+
+int
+clext_get_displaystart(struct vgamode_s *vmode_g)
+{
+ u16 crtc_addr = stdvga_get_crtc();
+ u8 b2 = stdvga_crtc_read(crtc_addr, 0x0c);
+ u8 b1 = stdvga_crtc_read(crtc_addr, 0x0d);
+ u8 b3 = stdvga_crtc_read(crtc_addr, 0x1b);
+ u8 b4 = stdvga_crtc_read(crtc_addr, 0x1d);
+ int val = (b1 | (b2<<8) | ((b3 & 0x01) << 16) | ((b3 & 0x0c) << 15)
+ | ((b4 & 0x80) << 12));
+ return val * 4 / stdvga_vram_ratio(vmode_g);
+}
+
+int
+clext_set_displaystart(struct vgamode_s *vmode_g, int val)
+{
+ u16 crtc_addr = stdvga_get_crtc();
+ val = val * stdvga_vram_ratio(vmode_g) / 4;
+ stdvga_crtc_write(crtc_addr, 0x0d, val);
+ stdvga_crtc_write(crtc_addr, 0x0c, val >> 8);
+ stdvga_crtc_mask(crtc_addr, 0x1d, 0x80, (val & 0x0800) >> 4);
+ stdvga_crtc_mask(crtc_addr, 0x1b, 0x0d
+ , ((val & 0x0100) >> 8) | ((val & 0x0600) >> 7));
+ return 0;
+}
+
+int
+clext_save_restore(int cmd, u16 seg, void *data)
+{
+ if (cmd & SR_REGISTERS)
+ return -1;
+ return stdvga_save_restore(cmd, seg, data);
+}
+
+
+/****************************************************************
+ * Mode setting
+ ****************************************************************/
+
+static void
+cirrus_switch_mode_setregs(u16 *data, u16 port)
+{
+ for (;;) {
+ u16 val = GET_GLOBAL(*data);
+ if (val == 0xffff)
+ return;
+ outw(val, port);
+ data++;
+ }
+}
+
+static void
+cirrus_switch_mode(struct cirrus_mode_s *table)
+{
+ // Unlock cirrus special
+ stdvga_sequ_write(0x06, 0x12);
+ cirrus_switch_mode_setregs(GET_GLOBAL(table->seq), VGAREG_SEQU_ADDRESS);
+ cirrus_switch_mode_setregs(GET_GLOBAL(table->graph), VGAREG_GRDC_ADDRESS);
+ cirrus_switch_mode_setregs(GET_GLOBAL(table->crtc), stdvga_get_crtc());
+
+ stdvga_pelmask_write(0x00);
+ stdvga_pelmask_read();
+ stdvga_pelmask_read();
+ stdvga_pelmask_read();
+ stdvga_pelmask_read();
+ stdvga_pelmask_write(GET_GLOBAL(table->hidden_dac));
+ stdvga_pelmask_write(0xff);
+
+ u8 memmodel = GET_GLOBAL(table->info.memmodel);
+ u8 on = 0;
+ if (memmodel == MM_PLANAR)
+ on = 0x41;
+ else if (memmodel != MM_TEXT)
+ on = 0x01;
+ stdvga_attr_mask(0x10, 0x01, on);
+ stdvga_attrindex_write(0x20);
+}
+
+static void
+cirrus_enable_16k_granularity(void)
+{
+ stdvga_grdc_mask(0x0b, 0x00, 0x20);
+}
+
+static void
+cirrus_clear_vram(u16 fill)
+{
+ cirrus_enable_16k_granularity();
+ int count = GET_GLOBAL(VBE_total_memory) / (16 * 1024);
+ int i;
+ for (i=0; i<count; i++) {
+ stdvga_grdc_write(0x09, i);
+ memset16_far(SEG_GRAPH, 0, fill, 16 * 1024);
+ }
+ stdvga_grdc_write(0x09, 0x00);
+}
+
+int
+clext_set_mode(struct vgamode_s *vmode_g, int flags)
+{
+ if (!is_cirrus_mode(vmode_g)) {
+ cirrus_switch_mode(&mode_switchback);
+ dprintf(1, "cirrus mode switch regular\n");
+ return stdvga_set_mode(vmode_g, flags);
+ }
+ struct cirrus_mode_s *table_g = container_of(
+ vmode_g, struct cirrus_mode_s, info);
+ cirrus_switch_mode(table_g);
+ if (GET_GLOBAL(vmode_g->memmodel) == MM_PACKED && !(flags & MF_NOPALETTE))
+ stdvga_set_packed_palette();
+ if (!(flags & MF_LINEARFB))
+ cirrus_enable_16k_granularity();
+ if (!(flags & MF_NOCLEARMEM))
+ // fill with 0xff to keep win 2K happy
+ cirrus_clear_vram(flags & MF_LEGACY ? 0xffff : 0x0000);
+ return 0;
+}
+
+
+/****************************************************************
+ * extbios
+ ****************************************************************/
+
+static void
+clext_101280(struct bregs *regs)
+{
+ u8 v = stdvga_crtc_read(stdvga_get_crtc(), 0x27);
+ if (v == 0xa0)
+ // 5430
+ regs->ax = 0x0032;
+ else if (v == 0xb8)
+ // 5446
+ regs->ax = 0x0039;
+ else
+ regs->ax = 0x00ff;
+ regs->bx = 0x00;
+ return;
+}
+
+static void
+clext_101281(struct bregs *regs)
+{
+ // XXX
+ regs->ax = 0x0100;
+}
+
+static void
+clext_101282(struct bregs *regs)
+{
+ regs->al = stdvga_crtc_read(stdvga_get_crtc(), 0x27) & 0x03;
+ regs->ah = 0xAF;
+}
+
+static void
+clext_101285(struct bregs *regs)
+{
+ regs->al = GET_GLOBAL(VBE_total_memory) / (64*1024);
+}
+
+static void
+clext_10129a(struct bregs *regs)
+{
+ regs->ax = 0x4060;
+ regs->cx = 0x1132;
+}
+
+extern void a0h_callback(void);
+ASM16(
+ // fatal: not implemented yet
+ "a0h_callback:"
+ "cli\n"
+ "hlt\n"
+ "lretw");
+
+static void
+clext_1012a0(struct bregs *regs)
+{
+ struct vgamode_s *table_g = clext_find_mode(regs->al & 0x7f);
+ regs->ah = (table_g ? 1 : 0);
+ regs->bx = (u32)a0h_callback;
+ regs->ds = regs->si = regs->es = regs->di = 0xffff;
+}
+
+static void
+clext_1012a1(struct bregs *regs)
+{
+ regs->bx = 0x0e00; // IBM 8512/8513, color
+}
+
+static void
+clext_1012a2(struct bregs *regs)
+{
+ regs->al = 0x07; // HSync 31.5 - 64.0 kHz
+}
+
+static void
+clext_1012ae(struct bregs *regs)
+{
+ regs->al = 0x01; // High Refresh 75Hz
+}
+
+static void
+clext_1012XX(struct bregs *regs)
+{
+ debug_stub(regs);
+}
+
+void
+clext_1012(struct bregs *regs)
+{
+ switch (regs->bl) {
+ case 0x80: clext_101280(regs); break;
+ case 0x81: clext_101281(regs); break;
+ case 0x82: clext_101282(regs); break;
+ case 0x85: clext_101285(regs); break;
+ case 0x9a: clext_10129a(regs); break;
+ case 0xa0: clext_1012a0(regs); break;
+ case 0xa1: clext_1012a1(regs); break;
+ case 0xa2: clext_1012a2(regs); break;
+ case 0xae: clext_1012ae(regs); break;
+ default: clext_1012XX(regs); break;
+ }
+}
+
+
+/****************************************************************
+ * init
+ ****************************************************************/
+
+static int
+cirrus_check(void)
+{
+ stdvga_sequ_write(0x06, 0x92);
+ return stdvga_sequ_read(0x06) == 0x12;
+}
+
+static u8
+cirrus_get_memsize(void)
+{
+ // get DRAM band width
+ u8 v = stdvga_sequ_read(0x0f);
+ u8 x = (v >> 3) & 0x03;
+ if (x == 0x03 && v & 0x80)
+ // 4MB
+ return 0x40;
+ return 0x04 << x;
+}
+
+int
+clext_setup(void)
+{
+ int ret = stdvga_setup();
+ if (ret)
+ return ret;
+
+ dprintf(1, "cirrus init\n");
+ if (! cirrus_check())
+ return -1;
+ dprintf(1, "cirrus init 2\n");
+
+ // memory setup
+ stdvga_sequ_write(0x0a, stdvga_sequ_read(0x0f) & 0x18);
+ // set vga mode
+ stdvga_sequ_write(0x07, 0x00);
+ // reset bitblt
+ stdvga_grdc_write(0x31, 0x04);
+ stdvga_grdc_write(0x31, 0x00);
+
+ if (GET_GLOBAL(HaveRunInit))
+ return 0;
+
+ u32 lfb_addr = 0;
+ int bdf = GET_GLOBAL(VgaBDF);
+ if (CONFIG_VGA_PCI && bdf >= 0)
+ lfb_addr = (pci_config_readl(bdf, PCI_BASE_ADDRESS_0)
+ & PCI_BASE_ADDRESS_MEM_MASK);
+ SET_VGA(VBE_framebuffer, lfb_addr);
+ u16 totalmem = cirrus_get_memsize();
+ SET_VGA(VBE_total_memory, totalmem * 64 * 1024);
+ SET_VGA(VBE_win_granularity, 16);
+
+ return 0;
+}
diff --git a/qemu/roms/seabios/vgasrc/clext.h b/qemu/roms/seabios/vgasrc/clext.h
new file mode 100644
index 000000000..cf47a5bf6
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/clext.h
@@ -0,0 +1,20 @@
+#ifndef __CLEXT_H
+#define __CLEXT_H
+
+#include "types.h" // u16
+
+struct vgamode_s *clext_find_mode(int mode);
+void clext_list_modes(u16 seg, u16 *dest, u16 *last);
+int clext_get_window(struct vgamode_s *vmode_g, int window);
+int clext_set_window(struct vgamode_s *vmode_g, int window, int val);
+int clext_get_linelength(struct vgamode_s *vmode_g);
+int clext_set_linelength(struct vgamode_s *vmode_g, int val);
+int clext_get_displaystart(struct vgamode_s *vmode_g);
+int clext_set_displaystart(struct vgamode_s *vmode_g, int val);
+int clext_save_restore(int cmd, u16 seg, void *data);
+int clext_set_mode(struct vgamode_s *vmode_g, int flags);
+struct bregs;
+void clext_1012(struct bregs *regs);
+int clext_setup(void);
+
+#endif // clext.h
diff --git a/qemu/roms/seabios/vgasrc/geodevga.c b/qemu/roms/seabios/vgasrc/geodevga.c
new file mode 100644
index 000000000..f8f61c3a1
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/geodevga.c
@@ -0,0 +1,433 @@
+// Geode GX2/LX VGA functions
+//
+// Copyright (C) 2009 Chris Kindt
+//
+// Written for Google Summer of Code 2009 for the coreboot project
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "biosvar.h" // GET_BDA
+#include "farptr.h" // SET_FARVAR
+#include "geodevga.h" // geodevga_setup
+#include "hw/pci.h" // pci_config_readl
+#include "hw/pci_regs.h" // PCI_BASE_ADDRESS_0
+#include "output.h" // dprintf
+#include "stdvga.h" // stdvga_crtc_write
+#include "vgabios.h" // VGAREG_*
+
+
+/****************************************************************
+* MSR and High Mem access through VSA Virtual Register
+****************************************************************/
+
+static u64 geode_msr_read(u32 msrAddr)
+{
+ union u64_u32_u val;
+ asm __volatile__ (
+ "movw $0x0AC1C, %%dx \n"
+ "movl $0xFC530007, %%eax \n"
+ "outl %%eax, %%dx \n"
+ "addb $2, %%dl \n"
+ "inw %%dx, %%ax \n"
+ : "=a" (val.lo), "=d"(val.hi)
+ : "c"(msrAddr)
+ : "cc"
+ );
+
+ dprintf(4, "%s(0x%08x) = 0x%08x-0x%08x\n"
+ , __func__, msrAddr, val.hi, val.lo);
+ return val.val;
+}
+
+static void geode_msr_mask(u32 msrAddr, u64 off, u64 on)
+{
+ union u64_u32_u uand, uor;
+ uand.val = ~off;
+ uor.val = on;
+
+ dprintf(4, "%s(0x%08x, 0x%016llx, 0x%016llx)\n"
+ , __func__, msrAddr, off, on);
+
+ asm __volatile__ (
+ "push %%eax \n"
+ "movw $0x0AC1C, %%dx \n"
+ "movl $0xFC530007, %%eax \n"
+ "outl %%eax, %%dx \n"
+ "addb $2, %%dl \n"
+ "pop %%eax \n"
+ "outw %%ax, %%dx \n"
+ :
+ : "c"(msrAddr), "S" (uand.hi), "D" (uand.lo), "b" (uor.hi), "a" (uor.lo)
+ : "%edx","cc"
+ );
+}
+
+static u32 geode_mem_read(u32 addr)
+{
+ u32 val;
+ asm __volatile__ (
+ "movw $0x0AC1C, %%dx \n"
+ "movl $0xFC530001, %%eax \n"
+ "outl %%eax, %%dx \n"
+ "addb $2, %%dl \n"
+ "inw %%dx, %%ax \n"
+ : "=a" (val)
+ : "b"(addr)
+ : "cc"
+ );
+
+ return val;
+}
+
+static void geode_mem_mask(u32 addr, u32 off, u32 or)
+{
+ asm __volatile__ (
+ "movw $0x0AC1C, %%dx \n"
+ "movl $0xFC530001, %%eax \n"
+ "outl %%eax, %%dx \n"
+ "addb $2, %%dl \n"
+ "outw %%ax, %%dx \n"
+ :
+ : "b"(addr), "S" (~off), "D" (or)
+ : "%eax","cc"
+ );
+}
+
+#define VP_FP_START 0x400
+
+static u32 GeodeFB VAR16;
+static u32 GeodeDC VAR16;
+static u32 GeodeVP VAR16;
+
+static u32 geode_dc_read(int reg)
+{
+ u32 val = geode_mem_read(GET_GLOBAL(GeodeDC) + reg);
+ dprintf(4, "%s(0x%08x) = 0x%08x\n"
+ , __func__, GET_GLOBAL(GeodeDC) + reg, val);
+ return val;
+}
+
+static void geode_dc_write(int reg, u32 val)
+{
+ dprintf(4, "%s(0x%08x, 0x%08x)\n"
+ , __func__, GET_GLOBAL(GeodeDC) + reg, val);
+ geode_mem_mask(GET_GLOBAL(GeodeDC) + reg, ~0, val);
+}
+
+static void geode_dc_mask(int reg, u32 off, u32 on)
+{
+ dprintf(4, "%s(0x%08x, 0x%08x, 0x%08x)\n"
+ , __func__, GET_GLOBAL(GeodeDC) + reg, off, on);
+ geode_mem_mask(GET_GLOBAL(GeodeDC) + reg, off, on);
+}
+
+static u32 geode_vp_read(int reg)
+{
+ u32 val = geode_mem_read(GET_GLOBAL(GeodeVP) + reg);
+ dprintf(4, "%s(0x%08x) = 0x%08x\n"
+ , __func__, GET_GLOBAL(GeodeVP) + reg, val);
+ return val;
+}
+
+static void geode_vp_write(int reg, u32 val)
+{
+ dprintf(4, "%s(0x%08x, 0x%08x)\n"
+ , __func__, GET_GLOBAL(GeodeVP) + reg, val);
+ geode_mem_mask(GET_GLOBAL(GeodeVP) + reg, ~0, val);
+}
+
+static void geode_vp_mask(int reg, u32 off, u32 on)
+{
+ dprintf(4, "%s(0x%08x, 0x%08x, 0x%08x)\n"
+ , __func__, GET_GLOBAL(GeodeVP) + reg, off, on);
+ geode_mem_mask(GET_GLOBAL(GeodeVP) + reg, off, on);
+}
+
+static u32 geode_fp_read(int reg)
+{
+ u32 val = geode_mem_read(GET_GLOBAL(GeodeVP) + VP_FP_START + reg);
+ dprintf(4, "%s(0x%08x) = 0x%08x\n"
+ , __func__, GET_GLOBAL(GeodeVP) + VP_FP_START + reg, val);
+ return val;
+}
+
+static void geode_fp_write(int reg, u32 val)
+{
+ dprintf(4, "%s(0x%08x, 0x%08x)\n"
+ , __func__, GET_GLOBAL(GeodeVP) + VP_FP_START + reg, val);
+ geode_mem_mask(GET_GLOBAL(GeodeVP) + VP_FP_START + reg, ~0, val);
+}
+
+/****************************************************************
+ * Helper functions
+ ****************************************************************/
+
+static int legacyio_check(void)
+{
+ int ret=0;
+ u64 val;
+
+ if (CONFIG_VGA_GEODEGX2)
+ val = geode_msr_read(GLIU0_P2D_BM_4);
+ else
+ val = geode_msr_read(MSR_GLIU0_BASE4);
+ if ((val & 0xffffffff) != 0x0A0fffe0)
+ ret|=1;
+
+ val = geode_msr_read(GLIU0_IOD_BM_0);
+ if ((val & 0xffffffff) != 0x3c0ffff0)
+ ret|=2;
+
+ val = geode_msr_read(GLIU0_IOD_BM_1);
+ if ((val & 0xffffffff) != 0x3d0ffff0)
+ ret|=4;
+
+ return ret;
+}
+
+static u32 framebuffer_size(void)
+{
+ /* We use the P2D_R0 msr to read out the number of pages.
+ * One page has a size of 4k
+ *
+ * Bit Name Description
+ * 39:20 PMAX Physical Memory Address Max
+ * 19:0 PMIX Physical Memory Address Min
+ *
+ */
+ u64 msr = geode_msr_read(GLIU0_P2D_RO);
+
+ u32 pmax = (msr >> 20) & 0x000fffff;
+ u32 pmin = msr & 0x000fffff;
+
+ u32 val = pmax - pmin;
+ val += 1;
+
+ /* The page size is 4k */
+ return (val << 12);
+}
+
+/****************************************************************
+* Init Functions
+****************************************************************/
+
+static void geodevga_set_output_mode(void)
+{
+ u64 msr_addr;
+ u64 msr;
+
+ /* set output to crt and RGB/YUV */
+ if (CONFIG_VGA_GEODEGX2)
+ msr_addr = VP_MSR_CONFIG_GX2;
+ else
+ msr_addr = VP_MSR_CONFIG_LX;
+
+ /* set output mode (RGB/YUV) */
+ msr = geode_msr_read(msr_addr);
+ msr &= ~VP_MSR_CONFIG_FMT; // mask out FMT (bits 5:3)
+
+ if (CONFIG_VGA_OUTPUT_PANEL || CONFIG_VGA_OUTPUT_CRT_PANEL) {
+ msr |= VP_MSR_CONFIG_FMT_FP; // flat panel
+
+ if (CONFIG_VGA_OUTPUT_CRT_PANEL) {
+ msr |= VP_MSR_CONFIG_FPC; // simultaneous Flat Panel and CRT
+ dprintf(1, "output: simultaneous Flat Panel and CRT\n");
+ } else {
+ msr &= ~VP_MSR_CONFIG_FPC; // no simultaneous Flat Panel and CRT
+ dprintf(1, "ouput: flat panel\n");
+ }
+ } else {
+ msr |= VP_MSR_CONFIG_FMT_CRT; // CRT only
+ dprintf(1, "output: CRT\n");
+ }
+ geode_msr_mask(msr_addr, ~msr, msr);
+}
+
+/* Set up the dc (display controller) portion of the geodelx
+* The dc provides hardware support for VGA graphics.
+*/
+static void dc_setup(void)
+{
+ dprintf(2, "DC_SETUP\n");
+
+ geode_dc_write(DC_UNLOCK, DC_LOCK_UNLOCK);
+
+ /* zero memory config */
+ geode_dc_write(DC_FB_ST_OFFSET, 0x0);
+ geode_dc_write(DC_CB_ST_OFFSET, 0x0);
+ geode_dc_write(DC_CURS_ST_OFFSET, 0x0);
+
+ geode_dc_mask(DC_DISPLAY_CFG, ~DC_CFG_MSK, DC_DISPLAY_CFG_GDEN|DC_DISPLAY_CFG_TRUP);
+ geode_dc_write(DC_GENERAL_CFG, DC_GENERAL_CFG_VGAE);
+
+ geode_dc_write(DC_UNLOCK, DC_LOCK_LOCK);
+}
+
+/* Setup the vp (video processor) portion of the geodelx
+* Under VGA modes the vp was handled by softvg from inside VSA2.
+* Without a softvg module, access is only available through a pci bar.
+* The High Mem Access virtual register is used to configure the
+* pci mmio bar from 16bit friendly io space.
+*/
+static void vp_setup(void)
+{
+ dprintf(2,"VP_SETUP\n");
+
+ geodevga_set_output_mode();
+
+ /* Set mmio registers
+ * there may be some timing issues here, the reads seem
+ * to slow things down enough work reliably
+ */
+
+ u32 reg = geode_vp_read(VP_MISC);
+ dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg);
+ geode_vp_write(VP_MISC, VP_DCFG_BYP_BOTH);
+ reg = geode_vp_read(VP_MISC);
+ dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg);
+
+ reg = geode_vp_read(VP_DCFG);
+ dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg);
+ geode_vp_mask(VP_DCFG, 0, VP_DCFG_CRT_EN|VP_DCFG_HSYNC_EN|VP_DCFG_VSYNC_EN|VP_DCFG_DAC_BL_EN|VP_DCFG_CRT_SKEW);
+ reg = geode_vp_read(VP_DCFG);
+ dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg);
+
+ /* setup flat panel */
+ if (CONFIG_VGA_OUTPUT_PANEL || CONFIG_VGA_OUTPUT_CRT_PANEL) {
+ u64 msr;
+
+ dprintf(1, "Setting up flat panel\n");
+ /* write timing register */
+ geode_fp_write(FP_PT1, 0x0);
+ geode_fp_write(FP_PT2, FP_PT2_SCRC);
+
+ /* set pad select for TFT/LVDS */
+ msr = VP_MSR_PADSEL_TFT_SEL_HIGH;
+ msr = msr << 32;
+ msr |= VP_MSR_PADSEL_TFT_SEL_LOW;
+ geode_msr_mask(VP_MSR_PADSEL, ~msr, msr);
+
+ /* turn the panel on (if it isn't already) */
+ reg = geode_fp_read(FP_PM);
+ reg |= FP_PM_P;
+ geode_fp_write(FP_PM, reg);
+ }
+}
+
+static u8 geode_crtc_01[] VAR16 = {
+ 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
+ 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x9b, 0x8d, 0x8f, 0x14, 0x1f, 0x97, 0xb9, 0xa3,
+ 0xff };
+static u8 geode_crtc_03[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
+ 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x9b, 0x8d, 0x8f, 0x28, 0x1f, 0x97, 0xb9, 0xa3,
+ 0xff };
+static u8 geode_crtc_04[] VAR16 = {
+ 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
+ 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9b, 0x8d, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xa2,
+ 0xff };
+static u8 geode_crtc_05[] VAR16 = {
+ 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
+ 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9b, 0x8e, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xa2,
+ 0xff };
+static u8 geode_crtc_06[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
+ 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9b, 0x8d, 0x8f, 0x28, 0x00, 0x97, 0xb9, 0xc2,
+ 0xff };
+static u8 geode_crtc_07[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
+ 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x9b, 0x8d, 0x8f, 0x28, 0x0f, 0x97, 0xb9, 0xa3,
+ 0xff };
+static u8 geode_crtc_0d[] VAR16 = {
+ 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9b, 0x8d, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xe3,
+ 0xff };
+static u8 geode_crtc_0e[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9b, 0x8d, 0x8f, 0x28, 0x00, 0x97, 0xb9, 0xe3,
+ 0xff };
+static u8 geode_crtc_0f[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x65, 0xb9, 0xe3,
+ 0xff };
+static u8 geode_crtc_11[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0x0b, 0x3e,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
+ 0xff };
+static u8 geode_crtc_13[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
+ 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9b, 0x8d, 0x8f, 0x28, 0x40, 0x98, 0xb9, 0xa3,
+ 0xff };
+
+int geodevga_setup(void)
+{
+ int ret = stdvga_setup();
+ if (ret)
+ return ret;
+
+ dprintf(1,"GEODEVGA_SETUP\n");
+
+ if ((ret=legacyio_check())) {
+ dprintf(1,"GEODEVGA_SETUP legacyio_check=0x%x\n",ret);
+ }
+
+ // Updated timings from geode datasheets, table 6-53 in particular
+ static u8 *new_crtc[] VAR16 = {
+ geode_crtc_01, geode_crtc_01, geode_crtc_03, geode_crtc_03,
+ geode_crtc_04, geode_crtc_05, geode_crtc_06, geode_crtc_07,
+ 0, 0, 0, 0, 0,
+ geode_crtc_0d, geode_crtc_0e, geode_crtc_0f, geode_crtc_0f,
+ geode_crtc_11, geode_crtc_11, geode_crtc_13 };
+ int i;
+ for (i=0; i<ARRAY_SIZE(new_crtc); i++) {
+ u8 *crtc = GET_GLOBAL(new_crtc[i]);
+ if (crtc)
+ stdvga_override_crtc(i, crtc);
+ }
+
+ if (GET_GLOBAL(VgaBDF) < 0)
+ // Device should be at 00:01.1
+ SET_VGA(VgaBDF, pci_to_bdf(0, 1, 1));
+
+ // setup geode struct which is used for register access
+ SET_VGA(GeodeFB, pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_0));
+ SET_VGA(GeodeDC, pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_2));
+ SET_VGA(GeodeVP, pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_3));
+
+ dprintf(1, "fb addr: 0x%08x\n", GET_GLOBAL(GeodeFB));
+ dprintf(1, "dc addr: 0x%08x\n", GET_GLOBAL(GeodeDC));
+ dprintf(1, "vp addr: 0x%08x\n", GET_GLOBAL(GeodeVP));
+
+ /* setup framebuffer */
+ geode_dc_write(DC_UNLOCK, DC_LOCK_UNLOCK);
+
+ /* read fb-bar from pci, then point dc to the fb base */
+ u32 fb = GET_GLOBAL(GeodeFB);
+ if (geode_dc_read(DC_GLIU0_MEM_OFFSET) != fb)
+ geode_dc_write(DC_GLIU0_MEM_OFFSET, fb);
+
+ geode_dc_write(DC_UNLOCK, DC_LOCK_LOCK);
+
+ u32 fb_size = framebuffer_size(); // in byte
+ dprintf(1, "%d KB of video memory at 0x%08x\n", fb_size / 1024, fb);
+
+ /* update VBE variables */
+ SET_VGA(VBE_framebuffer, fb);
+ SET_VGA(VBE_total_memory, fb_size / 1024 / 64); // number of 64K blocks
+
+ vp_setup();
+ dc_setup();
+
+ return 0;
+}
diff --git a/qemu/roms/seabios/vgasrc/geodevga.h b/qemu/roms/seabios/vgasrc/geodevga.h
new file mode 100644
index 000000000..61d78084d
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/geodevga.h
@@ -0,0 +1,89 @@
+// Geode GX2/LX VGA functions
+//
+// Copyright (C) 2009 Chris Kindt
+//
+// Writen for Google Summer of Code 2009 for the coreboot project
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#ifndef GEODEVGA_H
+#define GEODEVGA_H
+
+#define VRC_INDEX 0xAC1C // Index register
+#define VRC_DATA 0xAC1E // Data register
+#define VR_UNLOCK 0xFC53 // Virtual register unlock code
+
+// Graphics-specific registers:
+#define OEM_BAR0 0x50
+#define OEM_BAR1 0x54
+#define OEM_BAR2 0x58
+#define OEM_BAR3 0x5C
+
+#define DC_LOCK_LOCK 0x00000000
+#define DC_LOCK_UNLOCK 0x00004758
+
+/* LX MSRs */
+#define MSR_GLIU0 (1 << 28)
+#define MSR_GLIU0_BASE4 (MSR_GLIU0 + 0x23) /* LX */
+#define GLIU0_P2D_BM_4 (MSR_GLIU0 + 0x24) /* GX2 */
+#define GLIU0_P2D_RO (MSR_GLIU0 + 0x29)
+#define GLIU0_IOD_BM_0 (MSR_GLIU0 + 0xE0)
+#define GLIU0_IOD_BM_1 (MSR_GLIU0 + 0xE1)
+#define DC_SPARE 0x80000011
+#define VP_MSR_CONFIG_GX2 0xc0002001 /* GX2 */
+#define VP_MSR_CONFIG_LX 0x48002001 /* LX */
+#define VP_MSR_PADSEL 0x48002011
+
+#define VP_MSR_PADSEL_TFT_SEL_LOW 0xDFFFFFFF
+#define VP_MSR_PADSEL_TFT_SEL_HIGH 0x0000003F
+
+/* VP_MSR_CONFIG bits */
+#define VP_MSR_CONFIG_FMT_CRT (0)
+#define VP_MSR_CONFIG_FMT_FP (1 << 3)
+#define VP_MSR_CONFIG_FPC (1 << 15)
+#define VP_MSR_CONFIG_FMT ((1 << 3) | (1 << 4) | (1 << 5))
+
+
+/* DC REG OFFSET */
+#define DC_UNLOCK 0x0
+#define DC_GENERAL_CFG 0x4
+#define DC_DISPLAY_CFG 0x8
+#define DC_FB_ST_OFFSET 0x10
+#define DC_CB_ST_OFFSET 0x14
+#define DC_CURS_ST_OFFSET 0x18
+#define DC_GLIU0_MEM_OFFSET 0x84
+
+/* VP REG OFFSET */
+#define VP_VCFG 0x0
+#define VP_DCFG 0x8
+#define VP_MISC 0x50
+
+/* FP REG OFFSET */
+#define FP_PT1 0x00
+#define FP_PT2 0x08
+#define FP_PM 0x10
+
+
+/* DC bits */
+#define DC_GENERAL_CFG_VGAE (1 << 7)
+#define DC_DISPLAY_CFG_GDEN (1 << 3)
+#define DC_DISPLAY_CFG_TRUP (1 << 6)
+
+/* VP bits */
+#define VP_DCFG_CRT_EN (1 << 0)
+#define VP_DCFG_HSYNC_EN (1 << 1)
+#define VP_DCFG_VSYNC_EN (1 << 2)
+#define VP_DCFG_DAC_BL_EN (1 << 3)
+#define VP_DCFG_CRT_SKEW (1 << 16)
+#define VP_DCFG_BYP_BOTH (1 << 0)
+
+/* FP bits */
+#define FP_PM_P (1 << 24) /* panel power ctl */
+#define FP_PT2_SCRC (1 << 27) /* panel shift clock retrace activity ctl */
+
+/* Mask */
+#define DC_CFG_MSK 0xf000a6
+
+int geodevga_setup();
+
+#endif
diff --git a/qemu/roms/seabios/vgasrc/stdvga.c b/qemu/roms/seabios/vgasrc/stdvga.c
new file mode 100644
index 000000000..00a0fc57c
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/stdvga.c
@@ -0,0 +1,479 @@
+// Standard VGA driver code
+//
+// Copyright (C) 2009 Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2001-2008 the LGPL VGABios developers Team
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "biosvar.h" // GET_GLOBAL
+#include "farptr.h" // SET_FARVAR
+#include "stdvga.h" // stdvga_setup
+#include "string.h" // memset_far
+#include "vgabios.h" // struct vgamode_s
+#include "x86.h" // outb
+
+
+/****************************************************************
+ * Attribute control
+ ****************************************************************/
+
+void
+stdvga_set_border_color(u8 color)
+{
+ u8 v1 = color & 0x0f;
+ if (v1 & 0x08)
+ v1 += 0x08;
+ stdvga_attr_write(0x00, v1);
+
+ int i;
+ for (i = 1; i < 4; i++)
+ stdvga_attr_mask(i, 0x10, color & 0x10);
+}
+
+void
+stdvga_set_overscan_border_color(u8 color)
+{
+ stdvga_attr_write(0x11, color);
+}
+
+u8
+stdvga_get_overscan_border_color(void)
+{
+ return stdvga_attr_read(0x11);
+}
+
+void
+stdvga_set_palette(u8 palid)
+{
+ int i;
+ for (i = 1; i < 4; i++)
+ stdvga_attr_mask(i, 0x01, palid & 0x01);
+}
+
+void
+stdvga_set_all_palette_reg(u16 seg, u8 *data_far)
+{
+ int i;
+ for (i = 0; i < 0x10; i++) {
+ stdvga_attr_write(i, GET_FARVAR(seg, *data_far));
+ data_far++;
+ }
+ stdvga_attr_write(0x11, GET_FARVAR(seg, *data_far));
+}
+
+void
+stdvga_get_all_palette_reg(u16 seg, u8 *data_far)
+{
+ int i;
+ for (i = 0; i < 0x10; i++) {
+ SET_FARVAR(seg, *data_far, stdvga_attr_read(i));
+ data_far++;
+ }
+ SET_FARVAR(seg, *data_far, stdvga_attr_read(0x11));
+}
+
+void
+stdvga_toggle_intensity(u8 flag)
+{
+ stdvga_attr_mask(0x10, 0x08, (flag & 0x01) << 3);
+}
+
+void
+stdvga_select_video_dac_color_page(u8 flag, u8 data)
+{
+ if (!(flag & 0x01)) {
+ // select paging mode
+ stdvga_attr_mask(0x10, 0x80, data << 7);
+ return;
+ }
+ // select page
+ u8 val = stdvga_attr_read(0x10);
+ if (!(val & 0x80))
+ data <<= 2;
+ data &= 0x0f;
+ stdvga_attr_write(0x14, data);
+}
+
+void
+stdvga_read_video_dac_state(u8 *pmode, u8 *curpage)
+{
+ u8 val1 = stdvga_attr_read(0x10) >> 7;
+ u8 val2 = stdvga_attr_read(0x14) & 0x0f;
+ if (!(val1 & 0x01))
+ val2 >>= 2;
+ *pmode = val1;
+ *curpage = val2;
+}
+
+
+/****************************************************************
+ * DAC control
+ ****************************************************************/
+
+void
+stdvga_perform_gray_scale_summing(u16 start, u16 count)
+{
+ stdvga_attrindex_write(0x00);
+ int i;
+ for (i = start; i < start+count; i++) {
+ u8 rgb[3];
+ stdvga_dac_read(GET_SEG(SS), rgb, i, 1);
+
+ // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue )
+ u16 intensity = ((77 * rgb[0] + 151 * rgb[1] + 28 * rgb[2]) + 0x80) >> 8;
+ if (intensity > 0x3f)
+ intensity = 0x3f;
+ rgb[0] = rgb[1] = rgb[2] = intensity;
+
+ stdvga_dac_write(GET_SEG(SS), rgb, i, 1);
+ }
+ stdvga_attrindex_write(0x20);
+}
+
+
+/****************************************************************
+ * Memory control
+ ****************************************************************/
+
+void
+stdvga_set_text_block_specifier(u8 spec)
+{
+ stdvga_sequ_write(0x03, spec);
+}
+
+// Enable reads and writes to the given "plane" when in planar4 mode.
+void
+stdvga_planar4_plane(int plane)
+{
+ if (plane < 0) {
+ // Return to default mode (read plane0, write all planes)
+ stdvga_sequ_write(0x02, 0x0f);
+ stdvga_grdc_write(0x04, 0);
+ } else {
+ stdvga_sequ_write(0x02, 1<<plane);
+ stdvga_grdc_write(0x04, plane);
+ }
+}
+
+
+/****************************************************************
+ * Font loading
+ ****************************************************************/
+
+static void
+get_font_access(void)
+{
+ stdvga_sequ_write(0x00, 0x01);
+ stdvga_sequ_write(0x02, 0x04);
+ stdvga_sequ_write(0x04, 0x07);
+ stdvga_sequ_write(0x00, 0x03);
+ stdvga_grdc_write(0x04, 0x02);
+ stdvga_grdc_write(0x05, 0x00);
+ stdvga_grdc_write(0x06, 0x04);
+}
+
+static void
+release_font_access(void)
+{
+ stdvga_sequ_write(0x00, 0x01);
+ stdvga_sequ_write(0x02, 0x03);
+ stdvga_sequ_write(0x04, 0x03);
+ stdvga_sequ_write(0x00, 0x03);
+ u16 v = (stdvga_misc_read() & 0x01) ? 0x0e : 0x0a;
+ stdvga_grdc_write(0x06, v);
+ stdvga_grdc_write(0x04, 0x00);
+ stdvga_grdc_write(0x05, 0x10);
+}
+
+void
+stdvga_load_font(u16 seg, void *src_far, u16 count
+ , u16 start, u8 destflags, u8 fontsize)
+{
+ get_font_access();
+ u16 blockaddr = ((destflags & 0x03) << 14) + ((destflags & 0x04) << 11);
+ void *dest_far = (void*)(blockaddr + start*32);
+ u16 i;
+ for (i = 0; i < count; i++)
+ memcpy_far(SEG_GRAPH, dest_far + i*32
+ , seg, src_far + i*fontsize, fontsize);
+ release_font_access();
+}
+
+
+/****************************************************************
+ * CRTC registers
+ ****************************************************************/
+
+u16
+stdvga_get_crtc(void)
+{
+ if (stdvga_misc_read() & 1)
+ return VGAREG_VGA_CRTC_ADDRESS;
+ return VGAREG_MDA_CRTC_ADDRESS;
+}
+
+// Ratio between system visible framebuffer ram and the actual videoram used.
+int
+stdvga_vram_ratio(struct vgamode_s *vmode_g)
+{
+ switch (GET_GLOBAL(vmode_g->memmodel)) {
+ case MM_TEXT:
+ return 2;
+ case MM_CGA:
+ return 4 / GET_GLOBAL(vmode_g->depth);
+ case MM_PLANAR:
+ return 4;
+ default:
+ return 1;
+ }
+}
+
+void
+stdvga_set_cursor_shape(u16 cursor_type)
+{
+ u16 crtc_addr = stdvga_get_crtc();
+ stdvga_crtc_write(crtc_addr, 0x0a, cursor_type >> 8);
+ stdvga_crtc_write(crtc_addr, 0x0b, cursor_type);
+}
+
+void
+stdvga_set_cursor_pos(int address)
+{
+ u16 crtc_addr = stdvga_get_crtc();
+ address /= 2; // Assume we're in text mode.
+ stdvga_crtc_write(crtc_addr, 0x0e, address >> 8);
+ stdvga_crtc_write(crtc_addr, 0x0f, address);
+}
+
+void
+stdvga_set_scan_lines(u8 lines)
+{
+ stdvga_crtc_mask(stdvga_get_crtc(), 0x09, 0x1f, lines - 1);
+}
+
+// Get vertical display end
+u16
+stdvga_get_vde(void)
+{
+ u16 crtc_addr = stdvga_get_crtc();
+ u16 vde = stdvga_crtc_read(crtc_addr, 0x12);
+ u8 ovl = stdvga_crtc_read(crtc_addr, 0x07);
+ vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
+ return vde;
+}
+
+int
+stdvga_get_window(struct vgamode_s *vmode_g, int window)
+{
+ return -1;
+}
+
+int
+stdvga_set_window(struct vgamode_s *vmode_g, int window, int val)
+{
+ return -1;
+}
+
+int
+stdvga_get_linelength(struct vgamode_s *vmode_g)
+{
+ u8 val = stdvga_crtc_read(stdvga_get_crtc(), 0x13);
+ return val * 8 / stdvga_vram_ratio(vmode_g);
+}
+
+int
+stdvga_set_linelength(struct vgamode_s *vmode_g, int val)
+{
+ val = DIV_ROUND_UP(val * stdvga_vram_ratio(vmode_g), 8);
+ stdvga_crtc_write(stdvga_get_crtc(), 0x13, val);
+ return 0;
+}
+
+int
+stdvga_get_displaystart(struct vgamode_s *vmode_g)
+{
+ u16 crtc_addr = stdvga_get_crtc();
+ int addr = (stdvga_crtc_read(crtc_addr, 0x0c) << 8
+ | stdvga_crtc_read(crtc_addr, 0x0d));
+ return addr * 4 / stdvga_vram_ratio(vmode_g);
+}
+
+int
+stdvga_set_displaystart(struct vgamode_s *vmode_g, int val)
+{
+ u16 crtc_addr = stdvga_get_crtc();
+ val = val * stdvga_vram_ratio(vmode_g) / 4;
+ stdvga_crtc_write(crtc_addr, 0x0c, val >> 8);
+ stdvga_crtc_write(crtc_addr, 0x0d, val);
+ return 0;
+}
+
+int
+stdvga_get_dacformat(struct vgamode_s *vmode_g)
+{
+ return -1;
+}
+
+int
+stdvga_set_dacformat(struct vgamode_s *vmode_g, int val)
+{
+ return -1;
+}
+
+
+/****************************************************************
+ * Save/Restore state
+ ****************************************************************/
+
+struct saveVideoHardware {
+ u8 sequ_index;
+ u8 crtc_index;
+ u8 grdc_index;
+ u8 actl_index;
+ u8 feature;
+ u8 sequ_regs[4];
+ u8 sequ0;
+ u8 crtc_regs[25];
+ u8 actl_regs[20];
+ u8 grdc_regs[9];
+ u16 crtc_addr;
+ u8 plane_latch[4];
+} PACKED;
+
+static void
+stdvga_save_hw_state(u16 seg, struct saveVideoHardware *info)
+{
+ u16 crtc_addr = stdvga_get_crtc();
+ SET_FARVAR(seg, info->sequ_index, inb(VGAREG_SEQU_ADDRESS));
+ SET_FARVAR(seg, info->crtc_index, inb(crtc_addr));
+ SET_FARVAR(seg, info->grdc_index, inb(VGAREG_GRDC_ADDRESS));
+ SET_FARVAR(seg, info->actl_index, stdvga_attrindex_read());
+ SET_FARVAR(seg, info->feature, inb(VGAREG_READ_FEATURE_CTL));
+
+ int i;
+ for (i=0; i<4; i++)
+ SET_FARVAR(seg, info->sequ_regs[i], stdvga_sequ_read(i+1));
+ SET_FARVAR(seg, info->sequ0, stdvga_sequ_read(0));
+
+ for (i=0; i<25; i++)
+ SET_FARVAR(seg, info->crtc_regs[i], stdvga_crtc_read(crtc_addr, i));
+
+ for (i=0; i<20; i++)
+ SET_FARVAR(seg, info->actl_regs[i], stdvga_attr_read(i));
+
+ for (i=0; i<9; i++)
+ SET_FARVAR(seg, info->grdc_regs[i], stdvga_grdc_read(i));
+
+ SET_FARVAR(seg, info->crtc_addr, crtc_addr);
+
+ /* XXX: read plane latches */
+ for (i=0; i<4; i++)
+ SET_FARVAR(seg, info->plane_latch[i], 0);
+}
+
+static void
+stdvga_restore_hw_state(u16 seg, struct saveVideoHardware *info)
+{
+ int i;
+ for (i=0; i<4; i++)
+ stdvga_sequ_write(i+1, GET_FARVAR(seg, info->sequ_regs[i]));
+ stdvga_sequ_write(0x00, GET_FARVAR(seg, info->sequ0));
+
+ // Disable CRTC write protection
+ u16 crtc_addr = GET_FARVAR(seg, info->crtc_addr);
+ stdvga_crtc_write(crtc_addr, 0x11, 0x00);
+ // Set CRTC regs
+ for (i=0; i<25; i++)
+ if (i != 0x11)
+ stdvga_crtc_write(crtc_addr, i, GET_FARVAR(seg, info->crtc_regs[i]));
+ // select crtc base address
+ stdvga_misc_mask(0x01, crtc_addr == VGAREG_VGA_CRTC_ADDRESS ? 0x01 : 0x00);
+
+ // enable write protection if needed
+ stdvga_crtc_write(crtc_addr, 0x11, GET_FARVAR(seg, info->crtc_regs[0x11]));
+
+ // Set Attribute Ctl
+ for (i=0; i<20; i++)
+ stdvga_attr_write(i, GET_FARVAR(seg, info->actl_regs[i]));
+ stdvga_attrindex_write(GET_FARVAR(seg, info->actl_index));
+
+ for (i=0; i<9; i++)
+ stdvga_grdc_write(i, GET_FARVAR(seg, info->grdc_regs[i]));
+
+ outb(GET_FARVAR(seg, info->sequ_index), VGAREG_SEQU_ADDRESS);
+ outb(GET_FARVAR(seg, info->crtc_index), crtc_addr);
+ outb(GET_FARVAR(seg, info->grdc_index), VGAREG_GRDC_ADDRESS);
+ outb(GET_FARVAR(seg, info->feature), crtc_addr - 0x4 + 0xa);
+}
+
+struct saveDACcolors {
+ u8 rwmode;
+ u8 peladdr;
+ u8 pelmask;
+ u8 dac[768];
+ u8 color_select;
+} PACKED;
+
+static void
+stdvga_save_dac_state(u16 seg, struct saveDACcolors *info)
+{
+ /* XXX: check this */
+ SET_FARVAR(seg, info->rwmode, inb(VGAREG_DAC_STATE));
+ SET_FARVAR(seg, info->peladdr, inb(VGAREG_DAC_WRITE_ADDRESS));
+ SET_FARVAR(seg, info->pelmask, stdvga_pelmask_read());
+ stdvga_dac_read(seg, info->dac, 0, 256);
+ SET_FARVAR(seg, info->color_select, 0);
+}
+
+static void
+stdvga_restore_dac_state(u16 seg, struct saveDACcolors *info)
+{
+ stdvga_pelmask_write(GET_FARVAR(seg, info->pelmask));
+ stdvga_dac_write(seg, info->dac, 0, 256);
+ outb(GET_FARVAR(seg, info->peladdr), VGAREG_DAC_WRITE_ADDRESS);
+}
+
+int
+stdvga_save_restore(int cmd, u16 seg, void *data)
+{
+ void *pos = data;
+ if (cmd & SR_HARDWARE) {
+ if (cmd & SR_SAVE)
+ stdvga_save_hw_state(seg, pos);
+ if (cmd & SR_RESTORE)
+ stdvga_restore_hw_state(seg, pos);
+ pos += sizeof(struct saveVideoHardware);
+ }
+ pos += bda_save_restore(cmd, seg, pos);
+ if (cmd & SR_DAC) {
+ if (cmd & SR_SAVE)
+ stdvga_save_dac_state(seg, pos);
+ if (cmd & SR_RESTORE)
+ stdvga_restore_dac_state(seg, pos);
+ pos += sizeof(struct saveDACcolors);
+ }
+ return pos - data;
+}
+
+
+/****************************************************************
+ * Misc
+ ****************************************************************/
+
+void
+stdvga_enable_video_addressing(u8 disable)
+{
+ u8 v = (disable & 1) ? 0x00 : 0x02;
+ stdvga_misc_mask(0x02, v);
+}
+
+int
+stdvga_setup(void)
+{
+ // switch to color mode and enable CPU access 480 lines
+ stdvga_misc_write(0xc3);
+ // more than 64k 3C4/04
+ stdvga_sequ_write(0x04, 0x02);
+
+ return 0;
+}
diff --git a/qemu/roms/seabios/vgasrc/stdvga.h b/qemu/roms/seabios/vgasrc/stdvga.h
new file mode 100644
index 000000000..39753b4de
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/stdvga.h
@@ -0,0 +1,111 @@
+#ifndef __STDVGA_H
+#define __STDVGA_H
+
+#include "types.h" // u8
+
+// VGA registers
+#define VGAREG_ACTL_ADDRESS 0x3c0
+#define VGAREG_ACTL_WRITE_DATA 0x3c0
+#define VGAREG_ACTL_READ_DATA 0x3c1
+
+#define VGAREG_INPUT_STATUS 0x3c2
+#define VGAREG_WRITE_MISC_OUTPUT 0x3c2
+#define VGAREG_VIDEO_ENABLE 0x3c3
+#define VGAREG_SEQU_ADDRESS 0x3c4
+#define VGAREG_SEQU_DATA 0x3c5
+
+#define VGAREG_PEL_MASK 0x3c6
+#define VGAREG_DAC_STATE 0x3c7
+#define VGAREG_DAC_READ_ADDRESS 0x3c7
+#define VGAREG_DAC_WRITE_ADDRESS 0x3c8
+#define VGAREG_DAC_DATA 0x3c9
+
+#define VGAREG_READ_FEATURE_CTL 0x3ca
+#define VGAREG_READ_MISC_OUTPUT 0x3cc
+
+#define VGAREG_GRDC_ADDRESS 0x3ce
+#define VGAREG_GRDC_DATA 0x3cf
+
+#define VGAREG_MDA_CRTC_ADDRESS 0x3b4
+#define VGAREG_MDA_CRTC_DATA 0x3b5
+#define VGAREG_VGA_CRTC_ADDRESS 0x3d4
+#define VGAREG_VGA_CRTC_DATA 0x3d5
+
+#define VGAREG_MDA_WRITE_FEATURE_CTL 0x3ba
+#define VGAREG_VGA_WRITE_FEATURE_CTL 0x3da
+#define VGAREG_ACTL_RESET 0x3da
+
+#define VGAREG_MDA_MODECTL 0x3b8
+#define VGAREG_CGA_MODECTL 0x3d8
+#define VGAREG_CGA_PALETTE 0x3d9
+
+/* Video memory */
+#define SEG_GRAPH 0xA000
+#define SEG_CTEXT 0xB800
+#define SEG_MTEXT 0xB000
+
+// stdvgamodes.c
+struct vgamode_s *stdvga_find_mode(int mode);
+void stdvga_list_modes(u16 seg, u16 *dest, u16 *last);
+void stdvga_build_video_param(void);
+void stdvga_override_crtc(int mode, u8 *crtc);
+int stdvga_set_mode(struct vgamode_s *vmode_g, int flags);
+void stdvga_set_packed_palette(void);
+
+// stdvgaio.c
+u8 stdvga_pelmask_read(void);
+void stdvga_pelmask_write(u8 val);
+u8 stdvga_misc_read(void);
+void stdvga_misc_write(u8 value);
+void stdvga_misc_mask(u8 off, u8 on);
+u8 stdvga_sequ_read(u8 index);
+void stdvga_sequ_write(u8 index, u8 value);
+void stdvga_sequ_mask(u8 index, u8 off, u8 on);
+u8 stdvga_grdc_read(u8 index);
+void stdvga_grdc_write(u8 index, u8 value);
+void stdvga_grdc_mask(u8 index, u8 off, u8 on);
+u8 stdvga_crtc_read(u16 crtc_addr, u8 index);
+void stdvga_crtc_write(u16 crtc_addr, u8 index, u8 value);
+void stdvga_crtc_mask(u16 crtc_addr, u8 index, u8 off, u8 on);
+u8 stdvga_attr_read(u8 index);
+void stdvga_attr_write(u8 index, u8 value);
+void stdvga_attr_mask(u8 index, u8 off, u8 on);
+u8 stdvga_attrindex_read(void);
+void stdvga_attrindex_write(u8 value);
+void stdvga_dac_read(u16 seg, u8 *data_far, u8 start, int count);
+void stdvga_dac_write(u16 seg, u8 *data_far, u8 start, int count);
+
+// stdvga.c
+void stdvga_set_border_color(u8 color);
+void stdvga_set_overscan_border_color(u8 color);
+u8 stdvga_get_overscan_border_color(void);
+void stdvga_set_palette(u8 palid);
+void stdvga_set_all_palette_reg(u16 seg, u8 *data_far);
+void stdvga_get_all_palette_reg(u16 seg, u8 *data_far);
+void stdvga_toggle_intensity(u8 flag);
+void stdvga_select_video_dac_color_page(u8 flag, u8 data);
+void stdvga_read_video_dac_state(u8 *pmode, u8 *curpage);
+void stdvga_perform_gray_scale_summing(u16 start, u16 count);
+void stdvga_set_text_block_specifier(u8 spec);
+void stdvga_planar4_plane(int plane);
+void stdvga_load_font(u16 seg, void *src_far, u16 count
+ , u16 start, u8 destflags, u8 fontsize);
+u16 stdvga_get_crtc(void);
+int stdvga_vram_ratio(struct vgamode_s *vmode_g);
+void stdvga_set_cursor_shape(u16 cursor_type);
+void stdvga_set_cursor_pos(int address);
+void stdvga_set_scan_lines(u8 lines);
+u16 stdvga_get_vde(void);
+int stdvga_get_window(struct vgamode_s *vmode_g, int window);
+int stdvga_set_window(struct vgamode_s *vmode_g, int window, int val);
+int stdvga_get_linelength(struct vgamode_s *vmode_g);
+int stdvga_set_linelength(struct vgamode_s *vmode_g, int val);
+int stdvga_get_displaystart(struct vgamode_s *vmode_g);
+int stdvga_set_displaystart(struct vgamode_s *vmode_g, int val);
+int stdvga_get_dacformat(struct vgamode_s *vmode_g);
+int stdvga_set_dacformat(struct vgamode_s *vmode_g, int val);
+int stdvga_save_restore(int cmd, u16 seg, void *data);
+void stdvga_enable_video_addressing(u8 disable);
+int stdvga_setup(void);
+
+#endif // stdvga.h
diff --git a/qemu/roms/seabios/vgasrc/stdvgaio.c b/qemu/roms/seabios/vgasrc/stdvgaio.c
new file mode 100644
index 000000000..d6138c22b
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/stdvgaio.c
@@ -0,0 +1,185 @@
+// Standard VGA IO port access
+//
+// Copyright (C) 2012 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "farptr.h" // GET_FARVAR
+#include "stdvga.h" // stdvga_pelmask_read
+#include "x86.h" // inb
+
+u8
+stdvga_pelmask_read(void)
+{
+ return inb(VGAREG_PEL_MASK);
+}
+
+void
+stdvga_pelmask_write(u8 value)
+{
+ outb(value, VGAREG_PEL_MASK);
+}
+
+
+u8
+stdvga_misc_read(void)
+{
+ return inb(VGAREG_READ_MISC_OUTPUT);
+}
+
+void
+stdvga_misc_write(u8 value)
+{
+ outb(value, VGAREG_WRITE_MISC_OUTPUT);
+}
+
+void
+stdvga_misc_mask(u8 off, u8 on)
+{
+ stdvga_misc_write((stdvga_misc_read() & ~off) | on);
+}
+
+
+u8
+stdvga_sequ_read(u8 index)
+{
+ outb(index, VGAREG_SEQU_ADDRESS);
+ return inb(VGAREG_SEQU_DATA);
+}
+
+void
+stdvga_sequ_write(u8 index, u8 value)
+{
+ outw((value<<8) | index, VGAREG_SEQU_ADDRESS);
+}
+
+void
+stdvga_sequ_mask(u8 index, u8 off, u8 on)
+{
+ outb(index, VGAREG_SEQU_ADDRESS);
+ u8 v = inb(VGAREG_SEQU_DATA);
+ outb((v & ~off) | on, VGAREG_SEQU_DATA);
+}
+
+
+u8
+stdvga_grdc_read(u8 index)
+{
+ outb(index, VGAREG_GRDC_ADDRESS);
+ return inb(VGAREG_GRDC_DATA);
+}
+
+void
+stdvga_grdc_write(u8 index, u8 value)
+{
+ outw((value<<8) | index, VGAREG_GRDC_ADDRESS);
+}
+
+void
+stdvga_grdc_mask(u8 index, u8 off, u8 on)
+{
+ outb(index, VGAREG_GRDC_ADDRESS);
+ u8 v = inb(VGAREG_GRDC_DATA);
+ outb((v & ~off) | on, VGAREG_GRDC_DATA);
+}
+
+
+u8
+stdvga_crtc_read(u16 crtc_addr, u8 index)
+{
+ outb(index, crtc_addr);
+ return inb(crtc_addr + 1);
+}
+
+void
+stdvga_crtc_write(u16 crtc_addr, u8 index, u8 value)
+{
+ outw((value<<8) | index, crtc_addr);
+}
+
+void
+stdvga_crtc_mask(u16 crtc_addr, u8 index, u8 off, u8 on)
+{
+ outb(index, crtc_addr);
+ u8 v = inb(crtc_addr + 1);
+ outb((v & ~off) | on, crtc_addr + 1);
+}
+
+
+u8
+stdvga_attr_read(u8 index)
+{
+ inb(VGAREG_ACTL_RESET);
+ u8 orig = inb(VGAREG_ACTL_ADDRESS);
+ outb(index, VGAREG_ACTL_ADDRESS);
+ u8 v = inb(VGAREG_ACTL_READ_DATA);
+ inb(VGAREG_ACTL_RESET);
+ outb(orig, VGAREG_ACTL_ADDRESS);
+ return v;
+}
+
+void
+stdvga_attr_write(u8 index, u8 value)
+{
+ inb(VGAREG_ACTL_RESET);
+ u8 orig = inb(VGAREG_ACTL_ADDRESS);
+ outb(index, VGAREG_ACTL_ADDRESS);
+ outb(value, VGAREG_ACTL_WRITE_DATA);
+ outb(orig, VGAREG_ACTL_ADDRESS);
+}
+
+void
+stdvga_attr_mask(u8 index, u8 off, u8 on)
+{
+ inb(VGAREG_ACTL_RESET);
+ u8 orig = inb(VGAREG_ACTL_ADDRESS);
+ outb(index, VGAREG_ACTL_ADDRESS);
+ u8 v = inb(VGAREG_ACTL_READ_DATA);
+ outb((v & ~off) | on, VGAREG_ACTL_WRITE_DATA);
+ outb(orig, VGAREG_ACTL_ADDRESS);
+}
+
+u8
+stdvga_attrindex_read(void)
+{
+ inb(VGAREG_ACTL_RESET);
+ return inb(VGAREG_ACTL_ADDRESS);
+}
+
+void
+stdvga_attrindex_write(u8 value)
+{
+ inb(VGAREG_ACTL_RESET);
+ outb(value, VGAREG_ACTL_ADDRESS);
+}
+
+
+void
+stdvga_dac_read(u16 seg, u8 *data_far, u8 start, int count)
+{
+ outb(start, VGAREG_DAC_READ_ADDRESS);
+ while (count) {
+ SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA));
+ data_far++;
+ SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA));
+ data_far++;
+ SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA));
+ data_far++;
+ count--;
+ }
+}
+
+void
+stdvga_dac_write(u16 seg, u8 *data_far, u8 start, int count)
+{
+ outb(start, VGAREG_DAC_WRITE_ADDRESS);
+ while (count) {
+ outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA);
+ data_far++;
+ outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA);
+ data_far++;
+ outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA);
+ data_far++;
+ count--;
+ }
+}
diff --git a/qemu/roms/seabios/vgasrc/stdvgamodes.c b/qemu/roms/seabios/vgasrc/stdvgamodes.c
new file mode 100644
index 000000000..c553514fa
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/stdvgamodes.c
@@ -0,0 +1,523 @@
+// Standard VGA mode information.
+//
+// Copyright (C) 2009 Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2001-2008 the LGPL VGABios developers Team
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "biosvar.h" // GET_GLOBAL
+#include "output.h" // warn_internalerror
+#include "stdvga.h" // stdvga_find_mode
+#include "string.h" // memcpy_far
+#include "vgabios.h" // video_param_table
+
+
+/****************************************************************
+ * Video mode register definitions
+ ****************************************************************/
+
+/* Mono */
+static u8 palette0[] VAR16 = {
+ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
+ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
+ 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
+ 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
+ 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
+ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
+ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
+ 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
+ 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
+ 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f
+};
+
+static u8 palette1[] VAR16 = {
+ 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
+ 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
+ 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
+ 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
+ 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
+ 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
+ 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
+ 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
+ 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
+ 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
+ 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
+ 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
+ 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
+ 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
+ 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
+ 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f
+};
+
+static u8 palette2[] VAR16 = {
+ 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
+ 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a,
+ 0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f,
+ 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f,
+ 0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a,
+ 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a,
+ 0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f,
+ 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f,
+ 0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a,
+ 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a,
+ 0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f,
+ 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f,
+ 0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a,
+ 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a,
+ 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
+ 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f
+};
+
+static u8 palette3[] VAR16 = {
+ 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
+ 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
+ 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
+ 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
+ 0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b,
+ 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18,
+ 0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28,
+ 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f,
+ 0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f,
+ 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10,
+ 0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00,
+ 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00,
+ 0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f,
+ 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f,
+ 0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f,
+ 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27,
+
+ 0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f,
+ 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f,
+ 0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37,
+ 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f,
+ 0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f,
+ 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31,
+ 0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d,
+ 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d,
+ 0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a,
+ 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f,
+ 0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c,
+ 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07,
+ 0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00,
+ 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00,
+ 0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15,
+ 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c,
+
+ 0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c,
+ 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11,
+ 0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e,
+ 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e,
+ 0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18,
+ 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c,
+ 0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c,
+ 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16,
+ 0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14,
+ 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14,
+ 0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a,
+ 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c,
+ 0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10,
+ 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04,
+ 0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00,
+ 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00,
+
+ 0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c,
+ 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10,
+ 0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10,
+ 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a,
+ 0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08,
+ 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08,
+ 0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e,
+ 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10,
+ 0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10,
+ 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c,
+ 0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b,
+ 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b,
+ 0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f,
+ 0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10,
+ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
+ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00
+};
+
+static u8 sequ_01[] VAR16 = { 0x08, 0x03, 0x00, 0x02 };
+static u8 crtc_01[] VAR16 = {
+ 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
+ 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
+ 0xff };
+static u8 actl_01[] VAR16 = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x0c, 0x00, 0x0f, 0x08 };
+static u8 grdc_01[] VAR16 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff };
+static u8 sequ_03[] VAR16 = { 0x00, 0x03, 0x00, 0x02 };
+static u8 crtc_03[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+ 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
+ 0xff };
+static u8 sequ_04[] VAR16 = { 0x09, 0x03, 0x00, 0x02 };
+static u8 crtc_04[] VAR16 = {
+ 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
+ 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
+ 0xff };
+static u8 actl_04[] VAR16 = {
+ 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x01, 0x00, 0x03, 0x00 };
+static u8 grdc_04[] VAR16 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff };
+static u8 sequ_06[] VAR16 = { 0x01, 0x01, 0x00, 0x06 };
+static u8 crtc_06[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
+ 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2,
+ 0xff };
+static u8 actl_06[] VAR16 = {
+ 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
+ 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
+ 0x01, 0x00, 0x01, 0x00 };
+static u8 grdc_06[] VAR16 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0xff };
+static u8 crtc_07[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+ 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3,
+ 0xff };
+static u8 actl_07[] VAR16 = {
+ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x0e, 0x00, 0x0f, 0x08 };
+static u8 grdc_07[] VAR16 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff };
+static u8 sequ_0d[] VAR16 = { 0x09, 0x0f, 0x00, 0x06 };
+static u8 crtc_0d[] VAR16 = {
+ 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3,
+ 0xff };
+static u8 actl_0d[] VAR16 = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x01, 0x00, 0x0f, 0x00 };
+static u8 grdc_0d[] VAR16 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff };
+static u8 sequ_0e[] VAR16 = { 0x01, 0x0f, 0x00, 0x06 };
+static u8 crtc_0e[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3,
+ 0xff };
+static u8 crtc_0f[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
+ 0xff };
+static u8 actl_0f[] VAR16 = {
+ 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+ 0x01, 0x00, 0x01, 0x00 };
+static u8 actl_10[] VAR16 = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x01, 0x00, 0x0f, 0x00 };
+static u8 crtc_11[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
+ 0xff };
+static u8 actl_11[] VAR16 = {
+ 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
+ 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
+ 0x01, 0x00, 0x0f, 0x00 };
+static u8 sequ_13[] VAR16 = { 0x01, 0x0f, 0x00, 0x0e };
+static u8 crtc_13[] VAR16 = {
+ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
+ 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3,
+ 0xff };
+static u8 actl_13[] VAR16 = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x41, 0x00, 0x0f, 0x00 };
+static u8 grdc_13[] VAR16 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff };
+static u8 crtc_6A[] VAR16 = {
+ 0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x59, 0x8d, 0x57, 0x32, 0x00, 0x57, 0x73, 0xe3,
+ 0xff };
+
+#define PAL(x) x, sizeof(x)
+
+struct stdvga_mode_s {
+ u16 mode;
+ struct vgamode_s info;
+
+ u8 pelmask;
+ u8 *dac;
+ u16 dacsize;
+ u8 *sequ_regs;
+ u8 miscreg;
+ u8 *crtc_regs;
+ u8 *actl_regs;
+ u8 *grdc_regs;
+};
+
+static struct stdvga_mode_s vga_modes[] VAR16 = {
+ //mode { model tx ty bpp cw ch sstart }
+ // pelm dac sequ misc crtc actl grdc
+ {0x00, { MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT }
+ , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01},
+ {0x01, { MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT }
+ , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01},
+ {0x02, { MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT }
+ , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01},
+ {0x03, { MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT }
+ , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01},
+ {0x04, { MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT }
+ , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04},
+ {0x05, { MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT }
+ , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04},
+ {0x06, { MM_CGA, 640, 200, 1, 8, 8, SEG_CTEXT }
+ , 0xFF, PAL(palette1), sequ_06, 0x63, crtc_06, actl_06, grdc_06},
+ {0x07, { MM_TEXT, 80, 25, 4, 9, 16, SEG_MTEXT }
+ , 0xFF, PAL(palette0), sequ_03, 0x66, crtc_07, actl_07, grdc_07},
+ {0x0D, { MM_PLANAR, 320, 200, 4, 8, 8, SEG_GRAPH }
+ , 0xFF, PAL(palette1), sequ_0d, 0x63, crtc_0d, actl_0d, grdc_0d},
+ {0x0E, { MM_PLANAR, 640, 200, 4, 8, 8, SEG_GRAPH }
+ , 0xFF, PAL(palette1), sequ_0e, 0x63, crtc_0e, actl_0d, grdc_0d},
+ {0x0F, { MM_PLANAR, 640, 350, 1, 8, 14, SEG_GRAPH }
+ , 0xFF, PAL(palette0), sequ_0e, 0xa3, crtc_0f, actl_0f, grdc_0d},
+ {0x10, { MM_PLANAR, 640, 350, 4, 8, 14, SEG_GRAPH }
+ , 0xFF, PAL(palette2), sequ_0e, 0xa3, crtc_0f, actl_10, grdc_0d},
+ {0x11, { MM_PLANAR, 640, 480, 1, 8, 16, SEG_GRAPH }
+ , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_11, grdc_0d},
+ {0x12, { MM_PLANAR, 640, 480, 4, 8, 16, SEG_GRAPH }
+ , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_10, grdc_0d},
+ {0x13, { MM_PACKED, 320, 200, 8, 8, 8, SEG_GRAPH }
+ , 0xFF, PAL(palette3), sequ_13, 0x63, crtc_13, actl_13, grdc_13},
+ {0x6A, { MM_PLANAR, 800, 600, 4, 8, 16, SEG_GRAPH }
+ , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_6A, actl_10, grdc_0d},
+};
+
+
+/****************************************************************
+ * Mode functions
+ ****************************************************************/
+
+static int
+is_stdvga_mode(struct vgamode_s *vmode_g)
+{
+ return (vmode_g >= &vga_modes[0].info
+ && vmode_g <= &vga_modes[ARRAY_SIZE(vga_modes)-1].info);
+}
+
+struct vgamode_s *
+stdvga_find_mode(int mode)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(vga_modes); i++) {
+ struct stdvga_mode_s *stdmode_g = &vga_modes[i];
+ if (GET_GLOBAL(stdmode_g->mode) == mode)
+ return &stdmode_g->info;
+ }
+ return NULL;
+}
+
+void
+stdvga_list_modes(u16 seg, u16 *dest, u16 *last)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(vga_modes) && dest < last; i++) {
+ struct stdvga_mode_s *stdmode_g = &vga_modes[i];
+ u16 mode = GET_GLOBAL(stdmode_g->mode);
+ if (mode == 0xffff)
+ continue;
+ SET_FARVAR(seg, *dest, mode);
+ dest++;
+ }
+
+ SET_FARVAR(seg, *dest, 0xffff);
+}
+
+void
+stdvga_build_video_param(void)
+{
+ static u8 parammodes[] VAR16 = {
+ 0, 0, 0, 0, 0x04, 0x05, 0x06, 0x07,
+ 0, 0, 0, 0, 0, 0x0d, 0x0e, 0,
+ 0, 0x0f, 0x10, 0, 0, 0, 0, 0x01,
+ 0x03, 0x07, 0x11, 0x12, 0x13
+ };
+
+ int i;
+ for (i=0; i<ARRAY_SIZE(parammodes); i++) {
+ int mode = GET_GLOBAL(parammodes[i]);
+ if (! mode)
+ continue;
+ struct video_param_s *vparam_g = &video_param_table[i];
+ struct vgamode_s *vmode_g = stdvga_find_mode(mode);
+ if (!vmode_g)
+ continue;
+ int width = GET_GLOBAL(vmode_g->width);
+ int height = GET_GLOBAL(vmode_g->height);
+ u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
+ int cheight = GET_GLOBAL(vmode_g->cheight);
+ if (memmodel == MM_TEXT) {
+ SET_VGA(vparam_g->twidth, width);
+ SET_VGA(vparam_g->theightm1, height-1);
+ } else {
+ int cwidth = GET_GLOBAL(vmode_g->cwidth);
+ SET_VGA(vparam_g->twidth, width / cwidth);
+ SET_VGA(vparam_g->theightm1, (height / cheight) - 1);
+ }
+ SET_VGA(vparam_g->cheight, cheight);
+ SET_VGA(vparam_g->slength, calc_page_size(memmodel, width, height));
+ struct stdvga_mode_s *stdmode_g = container_of(
+ vmode_g, struct stdvga_mode_s, info);
+ memcpy_far(get_global_seg(), vparam_g->sequ_regs
+ , get_global_seg(), GET_GLOBAL(stdmode_g->sequ_regs)
+ , ARRAY_SIZE(vparam_g->sequ_regs));
+ SET_VGA(vparam_g->miscreg, GET_GLOBAL(stdmode_g->miscreg));
+ memcpy_far(get_global_seg(), vparam_g->crtc_regs
+ , get_global_seg(), GET_GLOBAL(stdmode_g->crtc_regs)
+ , ARRAY_SIZE(vparam_g->crtc_regs));
+ memcpy_far(get_global_seg(), vparam_g->actl_regs
+ , get_global_seg(), GET_GLOBAL(stdmode_g->actl_regs)
+ , ARRAY_SIZE(vparam_g->actl_regs));
+ memcpy_far(get_global_seg(), vparam_g->grdc_regs
+ , get_global_seg(), GET_GLOBAL(stdmode_g->grdc_regs)
+ , ARRAY_SIZE(vparam_g->grdc_regs));
+ }
+
+ // Fill available legacy modes in video_func_static table
+ u32 modes = 0;
+ for (i = 0; i < ARRAY_SIZE(vga_modes); i++) {
+ u16 mode = vga_modes[i].mode;
+ if (mode <= 0x13)
+ modes |= 1<<i;
+ }
+ SET_VGA(static_functionality.modes, modes);
+}
+
+void
+stdvga_override_crtc(int mode, u8 *crtc)
+{
+ struct vgamode_s *vmode_g = stdvga_find_mode(mode);
+ if (!vmode_g)
+ return;
+ struct stdvga_mode_s *stdmode_g = container_of(
+ vmode_g, struct stdvga_mode_s, info);
+ SET_VGA(stdmode_g->crtc_regs, crtc);
+}
+
+static void
+clear_screen(struct vgamode_s *vmode_g)
+{
+ switch (GET_GLOBAL(vmode_g->memmodel)) {
+ case MM_TEXT:
+ memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024);
+ break;
+ case MM_CGA:
+ memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 32*1024);
+ break;
+ default:
+ // XXX - old code gets/sets/restores sequ register 2 to 0xf -
+ // but it should always be 0xf anyway.
+ memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 64*1024);
+ }
+}
+
+int
+stdvga_set_mode(struct vgamode_s *vmode_g, int flags)
+{
+ if (! is_stdvga_mode(vmode_g)) {
+ warn_internalerror();
+ return -1;
+ }
+ struct stdvga_mode_s *stdmode_g = container_of(
+ vmode_g, struct stdvga_mode_s, info);
+
+ // if palette loading (bit 3 of modeset ctl = 0)
+ if (!(flags & MF_NOPALETTE)) { // Set the PEL mask
+ stdvga_pelmask_write(GET_GLOBAL(stdmode_g->pelmask));
+
+ // From which palette
+ u8 *palette_g = GET_GLOBAL(stdmode_g->dac);
+ u16 palsize = GET_GLOBAL(stdmode_g->dacsize) / 3;
+
+ // Always 256*3 values
+ stdvga_dac_write(get_global_seg(), palette_g, 0, palsize);
+ int i;
+ for (i = palsize; i < 0x0100; i++) {
+ static u8 rgb[3] VAR16;
+ stdvga_dac_write(get_global_seg(), rgb, i, 1);
+ }
+
+ if (flags & MF_GRAYSUM)
+ stdvga_perform_gray_scale_summing(0x00, 0x100);
+ }
+
+ // Set Attribute Ctl
+ u8 *regs = GET_GLOBAL(stdmode_g->actl_regs);
+ int i;
+ for (i = 0; i <= 0x13; i++)
+ stdvga_attr_write(i, GET_GLOBAL(regs[i]));
+ stdvga_attr_write(0x14, 0x00);
+
+ // Set Sequencer Ctl
+ stdvga_sequ_write(0x00, 0x03);
+ regs = GET_GLOBAL(stdmode_g->sequ_regs);
+ for (i = 1; i <= 4; i++)
+ stdvga_sequ_write(i, GET_GLOBAL(regs[i - 1]));
+
+ // Set Grafx Ctl
+ regs = GET_GLOBAL(stdmode_g->grdc_regs);
+ for (i = 0; i <= 8; i++)
+ stdvga_grdc_write(i, GET_GLOBAL(regs[i]));
+
+ // Set CRTC address VGA or MDA
+ u8 miscreg = GET_GLOBAL(stdmode_g->miscreg);
+ u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS;
+ if (!(miscreg & 1))
+ crtc_addr = VGAREG_MDA_CRTC_ADDRESS;
+
+ // Disable CRTC write protection
+ stdvga_crtc_write(crtc_addr, 0x11, 0x00);
+ // Set CRTC regs
+ regs = GET_GLOBAL(stdmode_g->crtc_regs);
+ for (i = 0; i <= 0x18; i++)
+ stdvga_crtc_write(crtc_addr, i, GET_GLOBAL(regs[i]));
+
+ // Set the misc register
+ stdvga_misc_write(miscreg);
+
+ // Enable video
+ stdvga_attrindex_write(0x20);
+
+ // Clear screen
+ if (!(flags & MF_NOCLEARMEM))
+ clear_screen(vmode_g);
+
+ // Write the fonts in memory
+ u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
+ if (memmodel == MM_TEXT)
+ stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, 0, 16);
+
+ return 0;
+}
+
+// Load the standard palette associated with 8bpp packed pixel vga modes.
+void
+stdvga_set_packed_palette(void)
+{
+ stdvga_dac_write(get_global_seg(), palette3, 0, sizeof(palette3) / 3);
+}
diff --git a/qemu/roms/seabios/vgasrc/vbe.c b/qemu/roms/seabios/vgasrc/vbe.c
new file mode 100644
index 000000000..af3d0ccb8
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/vbe.c
@@ -0,0 +1,426 @@
+// Video Bios Extensions handlers
+//
+// Copyright (C) 2012 Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2011 Julian Pidancet <julian.pidancet@citrix.com>
+// Copyright (C) 2001-2008 the LGPL VGABios developers Team
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "biosvar.h" // GET_GLOBAL
+#include "bregs.h" // struct bregs
+#include "config.h" // CONFIG_*
+#include "output.h" // dprintf
+#include "std/vbe.h" // struct vbe_info
+#include "string.h" // memset_far
+#include "vgabios.h" // handle_104f
+#include "vgahw.h" // vgahw_set_mode
+
+u32 VBE_total_memory VAR16 = 256 * 1024;
+u32 VBE_capabilities VAR16;
+u32 VBE_framebuffer VAR16;
+u16 VBE_win_granularity VAR16;
+
+static void
+vbe_104f00(struct bregs *regs)
+{
+ u16 seg = regs->es;
+ struct vbe_info *info = (void*)(regs->di+0);
+
+ if (GET_FARVAR(seg, info->signature) == VBE2_SIGNATURE) {
+ dprintf(4, "Get VBE Controller: VBE2 Signature found\n");
+ } else if (GET_FARVAR(seg, info->signature) == VESA_SIGNATURE) {
+ dprintf(4, "Get VBE Controller: VESA Signature found\n");
+ } else {
+ dprintf(4, "Get VBE Controller: Invalid Signature\n");
+ }
+
+ memset_far(seg, info, 0, sizeof(*info));
+
+ SET_FARVAR(seg, info->signature, VESA_SIGNATURE);
+
+ SET_FARVAR(seg, info->version, 0x0300);
+
+ SET_FARVAR(seg, info->oem_string,
+ SEGOFF(get_global_seg(), (u32)VBE_OEM_STRING));
+ SET_FARVAR(seg, info->capabilities, GET_GLOBAL(VBE_capabilities));
+
+ /* We generate our mode list in the reserved field of the info block */
+ u16 *destmode = (void*)info->reserved;
+ SET_FARVAR(seg, info->video_mode, SEGOFF(seg, (u32)destmode));
+
+ /* Total memory (in 64k blocks) */
+ SET_FARVAR(seg, info->total_memory
+ , GET_GLOBAL(VBE_total_memory) / (64*1024));
+
+ SET_FARVAR(seg, info->oem_vendor_string,
+ SEGOFF(get_global_seg(), (u32)VBE_VENDOR_STRING));
+ SET_FARVAR(seg, info->oem_product_string,
+ SEGOFF(get_global_seg(), (u32)VBE_PRODUCT_STRING));
+ SET_FARVAR(seg, info->oem_revision_string,
+ SEGOFF(get_global_seg(), (u32)VBE_REVISION_STRING));
+
+ /* Fill list of modes */
+ u16 *last = (void*)&info->reserved[sizeof(info->reserved)];
+ vgahw_list_modes(seg, destmode, last - 1);
+
+ regs->ax = 0x004f;
+}
+
+static void
+vbe_104f01(struct bregs *regs)
+{
+ u16 seg = regs->es;
+ struct vbe_mode_info *info = (void*)(regs->di+0);
+ u16 mode = regs->cx;
+
+ dprintf(1, "VBE mode info request: %x\n", mode);
+
+ struct vgamode_s *vmode_g = vgahw_find_mode(mode & ~MF_VBEFLAGS);
+ if (! vmode_g) {
+ dprintf(1, "VBE mode %x not found\n", mode);
+ regs->ax = 0x014f;
+ return;
+ }
+
+ memset_far(seg, info, 0, sizeof(*info));
+
+ // Basic information about video controller.
+ u32 win_granularity = GET_GLOBAL(VBE_win_granularity);
+ SET_FARVAR(seg, info->winA_attributes,
+ (win_granularity ? VBE_WINDOW_ATTRIBUTE_RELOCATABLE : 0) |
+ VBE_WINDOW_ATTRIBUTE_READABLE |
+ VBE_WINDOW_ATTRIBUTE_WRITEABLE);
+ SET_FARVAR(seg, info->winB_attributes, 0);
+ SET_FARVAR(seg, info->win_granularity, win_granularity);
+ SET_FARVAR(seg, info->win_size, 64); /* Bank size 64K */
+ SET_FARVAR(seg, info->winA_seg, GET_GLOBAL(vmode_g->sstart));
+ SET_FARVAR(seg, info->winB_seg, 0x0);
+ extern void entry_104f05(void);
+ SET_FARVAR(seg, info->win_func_ptr
+ , SEGOFF(get_global_seg(), (u32)entry_104f05));
+ // Basic information about mode.
+ int width = GET_GLOBAL(vmode_g->width);
+ int height = GET_GLOBAL(vmode_g->height);
+ int linesize = DIV_ROUND_UP(width * vga_bpp(vmode_g), 8);
+ SET_FARVAR(seg, info->bytes_per_scanline, linesize);
+ SET_FARVAR(seg, info->xres, width);
+ SET_FARVAR(seg, info->yres, height);
+ SET_FARVAR(seg, info->xcharsize, GET_GLOBAL(vmode_g->cwidth));
+ SET_FARVAR(seg, info->ycharsize, GET_GLOBAL(vmode_g->cheight));
+ int depth = GET_GLOBAL(vmode_g->depth);
+ SET_FARVAR(seg, info->bits_per_pixel, depth);
+ u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
+ SET_FARVAR(seg, info->mem_model, memmodel);
+ SET_FARVAR(seg, info->reserved0, 1);
+
+ // Mode specific info.
+ u16 mode_attr = VBE_MODE_ATTRIBUTE_SUPPORTED |
+ VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE |
+ VBE_MODE_ATTRIBUTE_COLOR_MODE |
+ VBE_MODE_ATTRIBUTE_GRAPHICS_MODE |
+ VBE_MODE_ATTRIBUTE_NOT_VGA_COMPATIBLE;
+ u32 framebuffer = 0;
+ int planes = 1, banks = 1;
+ u32 pages = GET_GLOBAL(VBE_total_memory) / ALIGN(height * linesize, 64*1024);
+ switch (memmodel) {
+ case MM_TEXT:
+ mode_attr &= ~VBE_MODE_ATTRIBUTE_GRAPHICS_MODE;
+ mode_attr |= VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT;
+ if (GET_GLOBAL(vmode_g->sstart) == SEG_MTEXT)
+ mode_attr &= ~VBE_MODE_ATTRIBUTE_COLOR_MODE;
+ pages = 1;
+ break;
+ case MM_CGA:
+ pages = 1;
+ banks = 2;
+ SET_FARVAR(seg, info->bank_size, 8);
+ break;
+ case MM_PLANAR:
+ planes = 4;
+ pages /= 4;
+ break;
+ default:
+ framebuffer = GET_GLOBAL(VBE_framebuffer);
+ if (framebuffer)
+ mode_attr |= VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE;
+ break;
+ }
+ if (pages > 128)
+ pages = 128;
+ if (pages < 2)
+ pages++;
+ SET_FARVAR(seg, info->mode_attributes, mode_attr);
+ SET_FARVAR(seg, info->planes, planes);
+ SET_FARVAR(seg, info->pages, pages - 1);
+ SET_FARVAR(seg, info->banks, banks);
+
+ // Pixel color breakdown
+ u8 r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos;
+ switch (depth) {
+ case 15: r_size = 5; r_pos = 10; g_size = 5; g_pos = 5;
+ b_size = 5; b_pos = 0; a_size = 1; a_pos = 15; break;
+ case 16: r_size = 5; r_pos = 11; g_size = 6; g_pos = 5;
+ b_size = 5; b_pos = 0; a_size = 0; a_pos = 0; break;
+ case 24: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8;
+ b_size = 8; b_pos = 0; a_size = 0; a_pos = 0; break;
+ case 32: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8;
+ b_size = 8; b_pos = 0; a_size = 8; a_pos = 24;
+ SET_FARVAR(seg, info->directcolor_info,
+ VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE);
+ break;
+ default: r_size = 0; r_pos = 0; g_size = 0; g_pos = 0;
+ b_size = 0; b_pos = 0; a_size = 0; a_pos = 0; break;
+ }
+ SET_FARVAR(seg, info->red_size, r_size);
+ SET_FARVAR(seg, info->red_pos, r_pos);
+ SET_FARVAR(seg, info->green_size, g_size);
+ SET_FARVAR(seg, info->green_pos, g_pos);
+ SET_FARVAR(seg, info->blue_size, b_size);
+ SET_FARVAR(seg, info->blue_pos, b_pos);
+ SET_FARVAR(seg, info->alpha_size, a_size);
+ SET_FARVAR(seg, info->alpha_pos, a_pos);
+
+ // Linear framebuffer info.
+ if (framebuffer) {
+ SET_FARVAR(seg, info->phys_base, framebuffer);
+
+ SET_FARVAR(seg, info->reserved1, 0);
+ SET_FARVAR(seg, info->reserved2, 0);
+ SET_FARVAR(seg, info->linear_bytes_per_scanline, linesize);
+ SET_FARVAR(seg, info->linear_pages, 0);
+ SET_FARVAR(seg, info->linear_red_size, r_size);
+ SET_FARVAR(seg, info->linear_red_pos, r_pos);
+ SET_FARVAR(seg, info->linear_green_size, g_size);
+ SET_FARVAR(seg, info->linear_green_pos, g_pos);
+ SET_FARVAR(seg, info->linear_blue_size, b_size);
+ SET_FARVAR(seg, info->linear_blue_pos, b_pos);
+ SET_FARVAR(seg, info->linear_alpha_size, a_size);
+ SET_FARVAR(seg, info->linear_alpha_pos, a_pos);
+ }
+
+ regs->ax = 0x004f;
+}
+
+static void
+vbe_104f02(struct bregs *regs)
+{
+ dprintf(1, "VBE mode set: %x\n", regs->bx);
+
+ int mode = regs->bx & ~MF_VBEFLAGS;
+ int flags = regs->bx & MF_VBEFLAGS;
+ int ret = vga_set_mode(mode, flags);
+
+ regs->ah = ret;
+ regs->al = 0x4f;
+}
+
+static void
+vbe_104f03(struct bregs *regs)
+{
+ regs->bx = GET_BDA_EXT(vbe_mode);
+ dprintf(1, "VBE current mode=%x\n", regs->bx);
+ regs->ax = 0x004f;
+}
+
+static void
+vbe_104f04(struct bregs *regs)
+{
+ u16 seg = regs->es;
+ void *data = (void*)(regs->bx+0);
+ u16 states = regs->cx;
+ u8 cmd = regs->dl;
+ if (states & ~0x0f || cmd > 2)
+ goto fail;
+ int ret = vgahw_save_restore(states | (cmd<<8), seg, data);
+ if (ret < 0)
+ goto fail;
+ if (cmd == 0)
+ regs->bx = ret / 64;
+ regs->ax = 0x004f;
+ return;
+fail:
+ regs->ax = 0x014f;
+}
+
+void VISIBLE16
+vbe_104f05(struct bregs *regs)
+{
+ if (regs->bh > 1 || regs->bl > 1)
+ goto fail;
+ if (GET_BDA_EXT(vbe_mode) & MF_LINEARFB) {
+ regs->ah = VBE_RETURN_STATUS_INVALID;
+ return;
+ }
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (! vmode_g)
+ goto fail;
+ if (regs->bh) {
+ int ret = vgahw_get_window(vmode_g, regs->bl);
+ if (ret < 0)
+ goto fail;
+ regs->dx = ret;
+ regs->ax = 0x004f;
+ return;
+ }
+ int ret = vgahw_set_window(vmode_g, regs->bl, regs->dx);
+ if (ret)
+ goto fail;
+ regs->ax = 0x004f;
+ return;
+fail:
+ regs->ax = 0x014f;
+}
+
+static void
+vbe_104f06(struct bregs *regs)
+{
+ if (regs->bl > 0x02)
+ goto fail;
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (! vmode_g)
+ goto fail;
+ int bpp = vga_bpp(vmode_g);
+
+ if (regs->bl == 0x00) {
+ int ret = vgahw_set_linelength(vmode_g, DIV_ROUND_UP(regs->cx * bpp, 8));
+ if (ret)
+ goto fail;
+ } else if (regs->bl == 0x02) {
+ int ret = vgahw_set_linelength(vmode_g, regs->cx);
+ if (ret)
+ goto fail;
+ }
+ int linelength = vgahw_get_linelength(vmode_g);
+ if (linelength < 0)
+ goto fail;
+
+ regs->bx = linelength;
+ regs->cx = (linelength * 8) / bpp;
+ regs->dx = GET_GLOBAL(VBE_total_memory) / linelength;
+ regs->ax = 0x004f;
+ return;
+fail:
+ regs->ax = 0x014f;
+}
+
+static void
+vbe_104f07(struct bregs *regs)
+{
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (! vmode_g)
+ goto fail;
+ int bpp = vga_bpp(vmode_g);
+ int linelength = vgahw_get_linelength(vmode_g);
+ if (linelength < 0)
+ goto fail;
+
+ int ret;
+ switch (regs->bl) {
+ case 0x80:
+ case 0x00:
+ ret = vgahw_set_displaystart(
+ vmode_g, DIV_ROUND_UP(regs->cx * bpp, 8) + linelength * regs->dx);
+ if (ret)
+ goto fail;
+ break;
+ case 0x01:
+ ret = vgahw_get_displaystart(vmode_g);
+ if (ret < 0)
+ goto fail;
+ regs->dx = ret / linelength;
+ regs->cx = (ret % linelength) * 8 / bpp;
+ break;
+ default:
+ goto fail;
+ }
+ regs->ax = 0x004f;
+ return;
+fail:
+ regs->ax = 0x014f;
+}
+
+static void
+vbe_104f08(struct bregs *regs)
+{
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (! vmode_g)
+ goto fail;
+ u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
+ if (memmodel == MM_DIRECT || memmodel == MM_YUV) {
+ regs->ax = 0x034f;
+ return;
+ }
+ if (regs->bl > 1)
+ goto fail;
+ if (regs->bl == 0) {
+ int ret = vgahw_set_dacformat(vmode_g, regs->bh);
+ if (ret < 0)
+ goto fail;
+ }
+ int ret = vgahw_get_dacformat(vmode_g);
+ if (ret < 0)
+ goto fail;
+ regs->bh = ret;
+ regs->ax = 0x004f;
+ return;
+fail:
+ regs->ax = 0x014f;
+}
+
+static void
+vbe_104f0a(struct bregs *regs)
+{
+ debug_stub(regs);
+ regs->ax = 0x0100;
+}
+
+static void
+vbe_104f10(struct bregs *regs)
+{
+ switch (regs->bl) {
+ case 0x00:
+ regs->bx = 0x0f30;
+ break;
+ case 0x01:
+ MASK_BDA_EXT(flags, BF_PM_MASK, regs->bh & BF_PM_MASK);
+ break;
+ case 0x02:
+ regs->bh = GET_BDA_EXT(flags) & BF_PM_MASK;
+ break;
+ default:
+ regs->ax = 0x014f;
+ return;
+ }
+ regs->ax = 0x004f;
+}
+
+static void
+vbe_104fXX(struct bregs *regs)
+{
+ debug_stub(regs);
+ regs->ax = 0x0100;
+}
+
+void noinline
+handle_104f(struct bregs *regs)
+{
+ if (!CONFIG_VGA_VBE) {
+ vbe_104fXX(regs);
+ return;
+ }
+
+ switch (regs->al) {
+ case 0x00: vbe_104f00(regs); break;
+ case 0x01: vbe_104f01(regs); break;
+ case 0x02: vbe_104f02(regs); break;
+ case 0x03: vbe_104f03(regs); break;
+ case 0x04: vbe_104f04(regs); break;
+ case 0x05: vbe_104f05(regs); break;
+ case 0x06: vbe_104f06(regs); break;
+ case 0x07: vbe_104f07(regs); break;
+ case 0x08: vbe_104f08(regs); break;
+ case 0x0a: vbe_104f0a(regs); break;
+ case 0x10: vbe_104f10(regs); break;
+ default: vbe_104fXX(regs); break;
+ }
+}
diff --git a/qemu/roms/seabios/vgasrc/vgabios.c b/qemu/roms/seabios/vgasrc/vgabios.c
new file mode 100644
index 000000000..4aa50e1c1
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/vgabios.c
@@ -0,0 +1,1176 @@
+// VGA bios implementation
+//
+// Copyright (C) 2009-2013 Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2001-2008 the LGPL VGABios developers Team
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "biosvar.h" // GET_BDA
+#include "bregs.h" // struct bregs
+#include "clext.h" // clext_1012
+#include "config.h" // CONFIG_*
+#include "output.h" // dprintf
+#include "std/vbe.h" // VBE_RETURN_STATUS_FAILED
+#include "stdvga.h" // stdvga_set_cursor_shape
+#include "string.h" // memset_far
+#include "vgabios.h" // calc_page_size
+#include "vgahw.h" // vgahw_set_mode
+
+
+/****************************************************************
+ * Helper functions
+ ****************************************************************/
+
+// Return the bits per pixel in system memory for a given mode.
+int
+vga_bpp(struct vgamode_s *vmode_g)
+{
+ switch (GET_GLOBAL(vmode_g->memmodel)) {
+ case MM_TEXT:
+ return 16;
+ case MM_PLANAR:
+ return 1;
+ }
+ u8 depth = GET_GLOBAL(vmode_g->depth);
+ if (depth > 8)
+ return ALIGN(depth, 8);
+ return depth;
+}
+
+u16
+calc_page_size(u8 memmodel, u16 width, u16 height)
+{
+ switch (memmodel) {
+ case MM_TEXT:
+ return ALIGN(width * height * 2, 2*1024);
+ case MM_CGA:
+ return 16*1024;
+ default:
+ return ALIGN(width * height / 8, 8*1024);
+ }
+}
+
+// Determine cursor shape (taking into account possible cursor scaling)
+u16
+get_cursor_shape(void)
+{
+ u16 cursor_type = GET_BDA(cursor_type);
+ u8 emulate_cursor = (GET_BDA(video_ctl) & 1) == 0;
+ if (!emulate_cursor)
+ return cursor_type;
+ u8 start = (cursor_type >> 8) & 0x3f;
+ u8 end = cursor_type & 0x1f;
+ u16 cheight = GET_BDA(char_height);
+ if (cheight <= 8 || end >= 8 || start >= 0x20)
+ return cursor_type;
+ if (end != (start + 1))
+ start = ((start + 1) * cheight / 8) - 1;
+ else
+ start = ((end + 1) * cheight / 8) - 2;
+ end = ((end + 1) * cheight / 8) - 1;
+ return (start << 8) | end;
+}
+
+static void
+set_cursor_shape(u16 cursor_type)
+{
+ vgafb_set_swcursor(0);
+ SET_BDA(cursor_type, cursor_type);
+ if (CONFIG_VGA_STDVGA_PORTS)
+ stdvga_set_cursor_shape(get_cursor_shape());
+}
+
+static void
+set_cursor_pos(struct cursorpos cp)
+{
+ u8 page = cp.page, x = cp.x, y = cp.y;
+
+ // Should not happen...
+ if (page > 7)
+ return;
+
+ vgafb_set_swcursor(0);
+
+ // Bios cursor pos
+ SET_BDA(cursor_pos[page], (y << 8) | x);
+
+ if (!CONFIG_VGA_STDVGA_PORTS)
+ return;
+
+ // Set the hardware cursor
+ u8 current = GET_BDA(video_page);
+ if (cp.page != current)
+ return;
+
+ // Calculate the memory address
+ stdvga_set_cursor_pos((int)text_address(cp));
+}
+
+struct cursorpos
+get_cursor_pos(u8 page)
+{
+ if (page == 0xff)
+ // special case - use current page
+ page = GET_BDA(video_page);
+ if (page > 7) {
+ struct cursorpos cp = { 0, 0, 0xfe };
+ return cp;
+ }
+ u16 xy = GET_BDA(cursor_pos[page]);
+ struct cursorpos cp = {xy, xy>>8, page};
+ return cp;
+}
+
+static void
+set_active_page(u8 page)
+{
+ if (page > 7)
+ return;
+
+ // Get the mode
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (!vmode_g)
+ return;
+
+ vgafb_set_swcursor(0);
+
+ // Calculate memory address of start of page
+ struct cursorpos cp = {0, 0, page};
+ int address = (int)text_address(cp);
+ vgahw_set_displaystart(vmode_g, address);
+
+ // And change the BIOS page
+ SET_BDA(video_pagestart, address);
+ SET_BDA(video_page, page);
+
+ dprintf(1, "Set active page %02x address %04x\n", page, address);
+
+ // Display the cursor, now the page is active
+ set_cursor_pos(get_cursor_pos(page));
+}
+
+static void
+set_scan_lines(u8 lines)
+{
+ stdvga_set_scan_lines(lines);
+ SET_BDA(char_height, lines);
+ u16 vde = stdvga_get_vde();
+ u8 rows = vde / lines;
+ SET_BDA(video_rows, rows - 1);
+ u16 cols = GET_BDA(video_cols);
+ SET_BDA(video_pagesize, calc_page_size(MM_TEXT, cols, rows));
+ if (lines == 8)
+ set_cursor_shape(0x0607);
+ else
+ set_cursor_shape(((lines - 3) << 8) | (lines - 2));
+}
+
+
+/****************************************************************
+ * Character writing
+ ****************************************************************/
+
+// Write a character to the screen and calculate new cursor position.
+static void
+write_char(struct cursorpos *pcp, struct carattr ca)
+{
+ vgafb_write_char(*pcp, ca);
+ pcp->x++;
+ // Do we need to wrap ?
+ if (pcp->x == GET_BDA(video_cols)) {
+ pcp->x = 0;
+ pcp->y++;
+ }
+}
+
+// Write a character to the screen at a given position. Implement
+// special characters and scroll the screen if necessary.
+static void
+write_teletype(struct cursorpos *pcp, struct carattr ca)
+{
+ switch (ca.car) {
+ case 7:
+ //FIXME should beep
+ break;
+ case 8:
+ if (pcp->x > 0)
+ pcp->x--;
+ break;
+ case '\r':
+ pcp->x = 0;
+ break;
+ case '\n':
+ pcp->y++;
+ break;
+ default:
+ write_char(pcp, ca);
+ break;
+ }
+
+ // Do we need to scroll ?
+ u16 nbrows = GET_BDA(video_rows);
+ if (pcp->y > nbrows) {
+ pcp->y--;
+
+ struct cursorpos dest = {0, 0, pcp->page};
+ struct cursorpos src = {0, 1, pcp->page};
+ struct cursorpos size = {GET_BDA(video_cols), nbrows};
+ vgafb_move_chars(dest, src, size);
+
+ struct cursorpos clr = {0, nbrows, pcp->page};
+ struct carattr attr = {' ', 0, 0};
+ struct cursorpos clrsize = {GET_BDA(video_cols), 1};
+ vgafb_clear_chars(clr, attr, clrsize);
+ }
+}
+
+
+/****************************************************************
+ * Save and restore bda state
+ ****************************************************************/
+
+struct saveBDAstate {
+ u8 bda_0x49[28];
+ u8 bda_0x84[6];
+ u16 vbe_mode;
+ struct segoff_s font0;
+ struct segoff_s font1;
+};
+
+int
+bda_save_restore(int cmd, u16 seg, void *data)
+{
+ if (!(cmd & SR_BDA))
+ return 0;
+ struct saveBDAstate *info = data;
+ if (cmd & SR_SAVE) {
+ memcpy_far(seg, info->bda_0x49, SEG_BDA, (void*)0x49
+ , sizeof(info->bda_0x49));
+ memcpy_far(seg, info->bda_0x84, SEG_BDA, (void*)0x84
+ , sizeof(info->bda_0x84));
+ SET_FARVAR(seg, info->vbe_mode, GET_BDA_EXT(vbe_mode));
+ SET_FARVAR(seg, info->font0, GET_IVT(0x1f));
+ SET_FARVAR(seg, info->font1, GET_IVT(0x43));
+ }
+ if (cmd & SR_RESTORE) {
+ memcpy_far(SEG_BDA, (void*)0x49, seg, info->bda_0x49
+ , sizeof(info->bda_0x49));
+ memcpy_far(SEG_BDA, (void*)0x84, seg, info->bda_0x84
+ , sizeof(info->bda_0x84));
+ u16 vbe_mode = GET_FARVAR(seg, info->vbe_mode);
+ SET_BDA_EXT(vbe_mode, vbe_mode);
+ struct vgamode_s *vmode_g = vgahw_find_mode(vbe_mode & ~MF_VBEFLAGS);
+ SET_BDA_EXT(vgamode_offset, (u32)vmode_g);
+ SET_IVT(0x1f, GET_FARVAR(seg, info->font0));
+ SET_IVT(0x43, GET_FARVAR(seg, info->font1));
+ }
+ return sizeof(*info);
+}
+
+
+/****************************************************************
+ * Mode setting
+ ****************************************************************/
+
+struct vgamode_s *
+get_current_mode(void)
+{
+ return (void*)(GET_BDA_EXT(vgamode_offset)+0);
+}
+
+// Setup BDA after a mode switch.
+int
+vga_set_mode(int mode, int flags)
+{
+ dprintf(1, "set VGA mode %x\n", mode);
+ struct vgamode_s *vmode_g = vgahw_find_mode(mode);
+ if (!vmode_g)
+ return VBE_RETURN_STATUS_FAILED;
+
+ vgafb_set_swcursor(0);
+
+ int ret = vgahw_set_mode(vmode_g, flags);
+ if (ret)
+ return ret;
+
+ // Set the BIOS mem
+ int width = GET_GLOBAL(vmode_g->width);
+ int height = GET_GLOBAL(vmode_g->height);
+ u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
+ int cheight = GET_GLOBAL(vmode_g->cheight);
+ if (mode < 0x100)
+ SET_BDA(video_mode, mode);
+ else
+ SET_BDA(video_mode, 0xff);
+ SET_BDA_EXT(vbe_mode, mode | (flags & MF_VBEFLAGS));
+ SET_BDA_EXT(vgamode_offset, (u32)vmode_g);
+ if (memmodel == MM_TEXT) {
+ SET_BDA(video_cols, width);
+ SET_BDA(video_rows, height-1);
+ SET_BDA(cursor_type, 0x0607);
+ } else {
+ int cwidth = GET_GLOBAL(vmode_g->cwidth);
+ SET_BDA(video_cols, width / cwidth);
+ SET_BDA(video_rows, (height / cheight) - 1);
+ SET_BDA(cursor_type, vga_emulate_text() ? 0x0607 : 0x0000);
+ }
+ SET_BDA(video_pagesize, calc_page_size(memmodel, width, height));
+ SET_BDA(crtc_address, CONFIG_VGA_STDVGA_PORTS ? stdvga_get_crtc() : 0);
+ SET_BDA(char_height, cheight);
+ SET_BDA(video_ctl, 0x60 | (flags & MF_NOCLEARMEM ? 0x80 : 0x00));
+ SET_BDA(video_switches, 0xF9);
+ SET_BDA(modeset_ctl, GET_BDA(modeset_ctl) & 0x7f);
+ int i;
+ for (i=0; i<8; i++)
+ SET_BDA(cursor_pos[i], 0x0000);
+ SET_BDA(video_pagestart, 0x0000);
+ SET_BDA(video_page, 0x00);
+
+ // Set the ints 0x1F and 0x43
+ SET_IVT(0x1f, SEGOFF(get_global_seg(), (u32)&vgafont8[128 * 8]));
+
+ switch (cheight) {
+ case 8:
+ SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont8));
+ break;
+ case 14:
+ SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont14));
+ break;
+ case 16:
+ SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont16));
+ break;
+ }
+
+ return 0;
+}
+
+
+/****************************************************************
+ * VGA int 10 handler
+ ****************************************************************/
+
+static void
+handle_1000(struct bregs *regs)
+{
+ int mode = regs->al & 0x7f;
+
+ // Set regs->al
+ if (mode > 7)
+ regs->al = 0x20;
+ else if (mode == 6)
+ regs->al = 0x3f;
+ else
+ regs->al = 0x30;
+
+ int flags = MF_LEGACY | (GET_BDA(modeset_ctl) & (MF_NOPALETTE|MF_GRAYSUM));
+ if (regs->al & 0x80)
+ flags |= MF_NOCLEARMEM;
+
+ vga_set_mode(mode, flags);
+}
+
+static void
+handle_1001(struct bregs *regs)
+{
+ set_cursor_shape(regs->cx);
+}
+
+static void
+handle_1002(struct bregs *regs)
+{
+ struct cursorpos cp = {regs->dl, regs->dh, regs->bh};
+ set_cursor_pos(cp);
+}
+
+static void
+handle_1003(struct bregs *regs)
+{
+ regs->cx = GET_BDA(cursor_type);
+ struct cursorpos cp = get_cursor_pos(regs->bh);
+ regs->dl = cp.x;
+ regs->dh = cp.y;
+}
+
+// Read light pen pos (unimplemented)
+static void
+handle_1004(struct bregs *regs)
+{
+ debug_stub(regs);
+ regs->ax = regs->bx = regs->cx = regs->dx = 0;
+}
+
+static void
+handle_1005(struct bregs *regs)
+{
+ set_active_page(regs->al);
+}
+
+static void
+verify_scroll(struct bregs *regs, int dir)
+{
+ u8 ulx = regs->cl, uly = regs->ch, lrx = regs->dl, lry = regs->dh;
+ u16 nbrows = GET_BDA(video_rows) + 1;
+ if (lry >= nbrows)
+ lry = nbrows - 1;
+ u16 nbcols = GET_BDA(video_cols);
+ if (lrx >= nbcols)
+ lrx = nbcols - 1;
+ int wincols = lrx - ulx + 1, winrows = lry - uly + 1;
+ if (wincols <= 0 || winrows <= 0)
+ return;
+
+ u8 page = GET_BDA(video_page);
+ int clearlines = regs->al, movelines = winrows - clearlines;
+ if (!clearlines || movelines <= 0) {
+ // Clear whole area.
+ struct cursorpos clr = {ulx, uly, page};
+ struct carattr attr = {' ', regs->bh, 1};
+ struct cursorpos clrsize = {wincols, winrows};
+ vgafb_clear_chars(clr, attr, clrsize);
+ return;
+ }
+
+ if (dir > 0) {
+ // Normal scroll
+ struct cursorpos dest = {ulx, uly, page};
+ struct cursorpos src = {ulx, uly + clearlines, page};
+ struct cursorpos size = {wincols, movelines};
+ vgafb_move_chars(dest, src, size);
+
+ struct cursorpos clr = {ulx, uly + movelines, page};
+ struct carattr attr = {' ', regs->bh, 1};
+ struct cursorpos clrsize = {wincols, clearlines};
+ vgafb_clear_chars(clr, attr, clrsize);
+ } else {
+ // Scroll down
+ struct cursorpos dest = {ulx, uly + clearlines, page};
+ struct cursorpos src = {ulx, uly, page};
+ struct cursorpos size = {wincols, movelines};
+ vgafb_move_chars(dest, src, size);
+
+ struct cursorpos clr = {ulx, uly, page};
+ struct carattr attr = {' ', regs->bh, 1};
+ struct cursorpos clrsize = {wincols, clearlines};
+ vgafb_clear_chars(clr, attr, clrsize);
+ }
+}
+
+static void
+handle_1006(struct bregs *regs)
+{
+ verify_scroll(regs, 1);
+}
+
+static void
+handle_1007(struct bregs *regs)
+{
+ verify_scroll(regs, -1);
+}
+
+static void
+handle_1008(struct bregs *regs)
+{
+ struct carattr ca = vgafb_read_char(get_cursor_pos(regs->bh));
+ regs->al = ca.car;
+ regs->ah = ca.attr;
+}
+
+static void noinline
+handle_1009(struct bregs *regs)
+{
+ struct carattr ca = {regs->al, regs->bl, 1};
+ struct cursorpos cp = get_cursor_pos(regs->bh);
+ int count = regs->cx;
+ while (count--)
+ write_char(&cp, ca);
+}
+
+static void noinline
+handle_100a(struct bregs *regs)
+{
+ struct carattr ca = {regs->al, regs->bl, 0};
+ struct cursorpos cp = get_cursor_pos(regs->bh);
+ int count = regs->cx;
+ while (count--)
+ write_char(&cp, ca);
+}
+
+
+static void
+handle_100b00(struct bregs *regs)
+{
+ stdvga_set_border_color(regs->bl);
+}
+
+static void
+handle_100b01(struct bregs *regs)
+{
+ stdvga_set_palette(regs->bl);
+}
+
+static void
+handle_100bXX(struct bregs *regs)
+{
+ debug_stub(regs);
+}
+
+static void
+handle_100b(struct bregs *regs)
+{
+ if (!CONFIG_VGA_STDVGA_PORTS) {
+ handle_100bXX(regs);
+ return;
+ }
+ switch (regs->bh) {
+ case 0x00: handle_100b00(regs); break;
+ case 0x01: handle_100b01(regs); break;
+ default: handle_100bXX(regs); break;
+ }
+}
+
+
+static void
+handle_100c(struct bregs *regs)
+{
+ // XXX - page (regs->bh) is unused
+ vgafb_write_pixel(regs->al, regs->cx, regs->dx);
+}
+
+static void
+handle_100d(struct bregs *regs)
+{
+ // XXX - page (regs->bh) is unused
+ regs->al = vgafb_read_pixel(regs->cx, regs->dx);
+}
+
+static void noinline
+handle_100e(struct bregs *regs)
+{
+ // Ralf Brown Interrupt list is WRONG on bh(page)
+ // We do output only on the current page !
+ struct carattr ca = {regs->al, regs->bl, 0};
+ struct cursorpos cp = get_cursor_pos(0xff);
+ write_teletype(&cp, ca);
+ set_cursor_pos(cp);
+}
+
+static void
+handle_100f(struct bregs *regs)
+{
+ regs->bh = GET_BDA(video_page);
+ regs->al = GET_BDA(video_mode) | (GET_BDA(video_ctl) & 0x80);
+ regs->ah = GET_BDA(video_cols);
+}
+
+
+static void
+handle_101000(struct bregs *regs)
+{
+ if (regs->bl > 0x14)
+ return;
+ stdvga_attr_write(regs->bl, regs->bh);
+}
+
+static void
+handle_101001(struct bregs *regs)
+{
+ stdvga_set_overscan_border_color(regs->bh);
+}
+
+static void
+handle_101002(struct bregs *regs)
+{
+ stdvga_set_all_palette_reg(regs->es, (u8*)(regs->dx + 0));
+}
+
+static void
+handle_101003(struct bregs *regs)
+{
+ stdvga_toggle_intensity(regs->bl);
+}
+
+static void
+handle_101007(struct bregs *regs)
+{
+ if (regs->bl > 0x14)
+ return;
+ regs->bh = stdvga_attr_read(regs->bl);
+}
+
+static void
+handle_101008(struct bregs *regs)
+{
+ regs->bh = stdvga_get_overscan_border_color();
+}
+
+static void
+handle_101009(struct bregs *regs)
+{
+ stdvga_get_all_palette_reg(regs->es, (u8*)(regs->dx + 0));
+}
+
+static void noinline
+handle_101010(struct bregs *regs)
+{
+ u8 rgb[3] = {regs->dh, regs->ch, regs->cl};
+ stdvga_dac_write(GET_SEG(SS), rgb, regs->bx, 1);
+}
+
+static void
+handle_101012(struct bregs *regs)
+{
+ stdvga_dac_write(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx);
+}
+
+static void
+handle_101013(struct bregs *regs)
+{
+ stdvga_select_video_dac_color_page(regs->bl, regs->bh);
+}
+
+static void noinline
+handle_101015(struct bregs *regs)
+{
+ u8 rgb[3];
+ stdvga_dac_read(GET_SEG(SS), rgb, regs->bx, 1);
+ regs->dh = rgb[0];
+ regs->ch = rgb[1];
+ regs->cl = rgb[2];
+}
+
+static void
+handle_101017(struct bregs *regs)
+{
+ stdvga_dac_read(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx);
+}
+
+static void
+handle_101018(struct bregs *regs)
+{
+ stdvga_pelmask_write(regs->bl);
+}
+
+static void
+handle_101019(struct bregs *regs)
+{
+ regs->bl = stdvga_pelmask_read();
+}
+
+static void
+handle_10101a(struct bregs *regs)
+{
+ stdvga_read_video_dac_state(&regs->bl, &regs->bh);
+}
+
+static void
+handle_10101b(struct bregs *regs)
+{
+ stdvga_perform_gray_scale_summing(regs->bx, regs->cx);
+}
+
+static void
+handle_1010XX(struct bregs *regs)
+{
+ debug_stub(regs);
+}
+
+static void
+handle_1010(struct bregs *regs)
+{
+ if (!CONFIG_VGA_STDVGA_PORTS) {
+ handle_1010XX(regs);
+ return;
+ }
+ switch (regs->al) {
+ case 0x00: handle_101000(regs); break;
+ case 0x01: handle_101001(regs); break;
+ case 0x02: handle_101002(regs); break;
+ case 0x03: handle_101003(regs); break;
+ case 0x07: handle_101007(regs); break;
+ case 0x08: handle_101008(regs); break;
+ case 0x09: handle_101009(regs); break;
+ case 0x10: handle_101010(regs); break;
+ case 0x12: handle_101012(regs); break;
+ case 0x13: handle_101013(regs); break;
+ case 0x15: handle_101015(regs); break;
+ case 0x17: handle_101017(regs); break;
+ case 0x18: handle_101018(regs); break;
+ case 0x19: handle_101019(regs); break;
+ case 0x1a: handle_10101a(regs); break;
+ case 0x1b: handle_10101b(regs); break;
+ default: handle_1010XX(regs); break;
+ }
+}
+
+
+static void
+handle_101100(struct bregs *regs)
+{
+ stdvga_load_font(regs->es, (void*)(regs->bp+0), regs->cx
+ , regs->dx, regs->bl, regs->bh);
+}
+
+static void
+handle_101101(struct bregs *regs)
+{
+ stdvga_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14);
+}
+
+static void
+handle_101102(struct bregs *regs)
+{
+ stdvga_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8);
+}
+
+static void
+handle_101103(struct bregs *regs)
+{
+ stdvga_set_text_block_specifier(regs->bl);
+}
+
+static void
+handle_101104(struct bregs *regs)
+{
+ stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16);
+}
+
+static void
+handle_101110(struct bregs *regs)
+{
+ stdvga_load_font(regs->es, (void*)(regs->bp+0), regs->cx
+ , regs->dx, regs->bl, regs->bh);
+ set_scan_lines(regs->bh);
+}
+
+static void
+handle_101111(struct bregs *regs)
+{
+ stdvga_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14);
+ set_scan_lines(14);
+}
+
+static void
+handle_101112(struct bregs *regs)
+{
+ stdvga_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8);
+ set_scan_lines(8);
+}
+
+static void
+handle_101114(struct bregs *regs)
+{
+ stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16);
+ set_scan_lines(16);
+}
+
+static void
+handle_101120(struct bregs *regs)
+{
+ SET_IVT(0x1f, SEGOFF(regs->es, regs->bp));
+}
+
+void
+load_gfx_font(u16 seg, u16 off, u8 height, u8 bl, u8 dl)
+{
+ u8 rows;
+
+ SET_IVT(0x43, SEGOFF(seg, off));
+ switch(bl) {
+ case 0:
+ rows = dl;
+ break;
+ case 1:
+ rows = 14;
+ break;
+ case 3:
+ rows = 43;
+ break;
+ case 2:
+ default:
+ rows = 25;
+ break;
+ }
+ SET_BDA(video_rows, rows - 1);
+ SET_BDA(char_height, height);
+}
+
+static void
+handle_101121(struct bregs *regs)
+{
+ load_gfx_font(regs->es, regs->bp, regs->cx, regs->bl, regs->dl);
+}
+
+static void
+handle_101122(struct bregs *regs)
+{
+ load_gfx_font(get_global_seg(), (u32)vgafont14, 14, regs->bl, regs->dl);
+}
+
+static void
+handle_101123(struct bregs *regs)
+{
+ load_gfx_font(get_global_seg(), (u32)vgafont8, 8, regs->bl, regs->dl);
+}
+
+static void
+handle_101124(struct bregs *regs)
+{
+ load_gfx_font(get_global_seg(), (u32)vgafont16, 16, regs->bl, regs->dl);
+}
+
+static void
+handle_101130(struct bregs *regs)
+{
+ switch (regs->bh) {
+ case 0x00: {
+ struct segoff_s so = GET_IVT(0x1f);
+ regs->es = so.seg;
+ regs->bp = so.offset;
+ break;
+ }
+ case 0x01: {
+ struct segoff_s so = GET_IVT(0x43);
+ regs->es = so.seg;
+ regs->bp = so.offset;
+ break;
+ }
+ case 0x02:
+ regs->es = get_global_seg();
+ regs->bp = (u32)vgafont14;
+ break;
+ case 0x03:
+ regs->es = get_global_seg();
+ regs->bp = (u32)vgafont8;
+ break;
+ case 0x04:
+ regs->es = get_global_seg();
+ regs->bp = (u32)vgafont8 + 128 * 8;
+ break;
+ case 0x05:
+ regs->es = get_global_seg();
+ regs->bp = (u32)vgafont14alt;
+ break;
+ case 0x06:
+ regs->es = get_global_seg();
+ regs->bp = (u32)vgafont16;
+ break;
+ case 0x07:
+ regs->es = get_global_seg();
+ regs->bp = (u32)vgafont16alt;
+ break;
+ default:
+ dprintf(1, "Get font info BH(%02x) was discarded\n", regs->bh);
+ return;
+ }
+ // Set byte/char of on screen font
+ regs->cx = GET_BDA(char_height) & 0xff;
+
+ // Set Highest char row
+ regs->dl = GET_BDA(video_rows);
+}
+
+static void
+handle_1011XX(struct bregs *regs)
+{
+ debug_stub(regs);
+}
+
+static void
+handle_1011(struct bregs *regs)
+{
+ if (CONFIG_VGA_STDVGA_PORTS) {
+ switch (regs->al) {
+ case 0x00: handle_101100(regs); return;
+ case 0x01: handle_101101(regs); return;
+ case 0x02: handle_101102(regs); return;
+ case 0x03: handle_101103(regs); return;
+ case 0x04: handle_101104(regs); return;
+ case 0x10: handle_101110(regs); return;
+ case 0x11: handle_101111(regs); return;
+ case 0x12: handle_101112(regs); return;
+ case 0x14: handle_101114(regs); return;
+ }
+ }
+ switch (regs->al) {
+ case 0x30: handle_101130(regs); break;
+ case 0x20: handle_101120(regs); break;
+ case 0x21: handle_101121(regs); break;
+ case 0x22: handle_101122(regs); break;
+ case 0x23: handle_101123(regs); break;
+ case 0x24: handle_101124(regs); break;
+ default: handle_1011XX(regs); break;
+ }
+}
+
+
+static void
+handle_101210(struct bregs *regs)
+{
+ u16 crtc_addr = GET_BDA(crtc_address);
+ if (crtc_addr == VGAREG_MDA_CRTC_ADDRESS)
+ regs->bx = 0x0103;
+ else
+ regs->bx = 0x0003;
+ regs->cx = GET_BDA(video_switches) & 0x0f;
+}
+
+static void
+handle_101230(struct bregs *regs)
+{
+ u8 mctl = GET_BDA(modeset_ctl);
+ u8 vswt = GET_BDA(video_switches);
+ switch (regs->al) {
+ case 0x00:
+ // 200 lines
+ mctl = (mctl & ~0x10) | 0x80;
+ vswt = (vswt & ~0x0f) | 0x08;
+ break;
+ case 0x01:
+ // 350 lines
+ mctl &= ~0x90;
+ vswt = (vswt & ~0x0f) | 0x09;
+ break;
+ case 0x02:
+ // 400 lines
+ mctl = (mctl & ~0x80) | 0x10;
+ vswt = (vswt & ~0x0f) | 0x09;
+ break;
+ default:
+ dprintf(1, "Select vert res (%02x) was discarded\n", regs->al);
+ break;
+ }
+ SET_BDA(modeset_ctl, mctl);
+ SET_BDA(video_switches, vswt);
+ regs->al = 0x12;
+}
+
+static void
+handle_101231(struct bregs *regs)
+{
+ u8 v = (regs->al & 0x01) << 3;
+ u8 mctl = GET_BDA(video_ctl) & ~0x08;
+ SET_BDA(video_ctl, mctl | v);
+ regs->al = 0x12;
+}
+
+static void
+handle_101232(struct bregs *regs)
+{
+ if (CONFIG_VGA_STDVGA_PORTS) {
+ stdvga_enable_video_addressing(regs->al);
+ regs->al = 0x12;
+ }
+}
+
+static void
+handle_101233(struct bregs *regs)
+{
+ u8 v = ((regs->al << 1) & 0x02) ^ 0x02;
+ u8 v2 = GET_BDA(modeset_ctl) & ~0x02;
+ SET_BDA(modeset_ctl, v | v2);
+ regs->al = 0x12;
+}
+
+static void
+handle_101234(struct bregs *regs)
+{
+ SET_BDA(video_ctl, (GET_BDA(video_ctl) & ~0x01) | (regs->al & 0x01));
+ regs->al = 0x12;
+}
+
+static void
+handle_101235(struct bregs *regs)
+{
+ debug_stub(regs);
+ regs->al = 0x12;
+}
+
+static void
+handle_101236(struct bregs *regs)
+{
+ debug_stub(regs);
+ regs->al = 0x12;
+}
+
+static void
+handle_1012XX(struct bregs *regs)
+{
+ debug_stub(regs);
+}
+
+static void
+handle_1012(struct bregs *regs)
+{
+ if (CONFIG_VGA_CIRRUS && regs->bl >= 0x80) {
+ clext_1012(regs);
+ return;
+ }
+
+ switch (regs->bl) {
+ case 0x10: handle_101210(regs); break;
+ case 0x30: handle_101230(regs); break;
+ case 0x31: handle_101231(regs); break;
+ case 0x32: handle_101232(regs); break;
+ case 0x33: handle_101233(regs); break;
+ case 0x34: handle_101234(regs); break;
+ case 0x35: handle_101235(regs); break;
+ case 0x36: handle_101236(regs); break;
+ default: handle_1012XX(regs); break;
+ }
+}
+
+
+// Write string
+static void noinline
+handle_1013(struct bregs *regs)
+{
+ struct cursorpos cp;
+ if (regs->dh == 0xff)
+ // if row=0xff special case : use current cursor position
+ cp = get_cursor_pos(regs->bh);
+ else
+ cp = (struct cursorpos) {regs->dl, regs->dh, regs->bh};
+
+ u16 count = regs->cx;
+ u8 *offset_far = (void*)(regs->bp + 0);
+ u8 attr = regs->bl;
+ while (count--) {
+ u8 car = GET_FARVAR(regs->es, *offset_far);
+ offset_far++;
+ if (regs->al & 2) {
+ attr = GET_FARVAR(regs->es, *offset_far);
+ offset_far++;
+ }
+
+ struct carattr ca = {car, attr, 1};
+ write_teletype(&cp, ca);
+ }
+
+ if (regs->al & 1)
+ set_cursor_pos(cp);
+}
+
+
+static void
+handle_101a00(struct bregs *regs)
+{
+ regs->bx = GET_BDA(dcc_index);
+ regs->al = 0x1a;
+}
+
+static void
+handle_101a01(struct bregs *regs)
+{
+ SET_BDA(dcc_index, regs->bl);
+ dprintf(1, "Alternate Display code (%02x) was discarded\n", regs->bh);
+ regs->al = 0x1a;
+}
+
+static void
+handle_101aXX(struct bregs *regs)
+{
+ debug_stub(regs);
+}
+
+static void
+handle_101a(struct bregs *regs)
+{
+ switch (regs->al) {
+ case 0x00: handle_101a00(regs); break;
+ case 0x01: handle_101a01(regs); break;
+ default: handle_101aXX(regs); break;
+ }
+}
+
+
+struct video_func_static static_functionality VAR16 = {
+ .modes = 0x00, // Filled in by stdvga_build_video_param()
+ .scanlines = 0x07, // 200, 350, 400 scan lines
+ .cblocks = 0x02, // mamimum number of visible charsets in text mode
+ .active_cblocks = 0x08, // total number of charset blocks in text mode
+ .misc_flags = 0x0ce7,
+};
+
+static void
+handle_101b(struct bregs *regs)
+{
+ u16 seg = regs->es;
+ struct video_func_info *info = (void*)(regs->di+0);
+ memset_far(seg, info, 0, sizeof(*info));
+ // Address of static functionality table
+ SET_FARVAR(seg, info->static_functionality
+ , SEGOFF(get_global_seg(), (u32)&static_functionality));
+
+ // Hard coded copy from BIOS area. Should it be cleaner ?
+ memcpy_far(seg, info->bda_0x49, SEG_BDA, (void*)0x49
+ , sizeof(info->bda_0x49));
+ memcpy_far(seg, info->bda_0x84, SEG_BDA, (void*)0x84
+ , sizeof(info->bda_0x84));
+
+ SET_FARVAR(seg, info->dcc_index, GET_BDA(dcc_index));
+ SET_FARVAR(seg, info->colors, 16);
+ SET_FARVAR(seg, info->pages, 8);
+ SET_FARVAR(seg, info->scan_lines, 2);
+ SET_FARVAR(seg, info->video_mem, 3);
+ regs->al = 0x1B;
+}
+
+
+static void
+handle_101c(struct bregs *regs)
+{
+ u16 seg = regs->es;
+ void *data = (void*)(regs->bx+0);
+ u16 states = regs->cx;
+ u8 cmd = regs->al;
+ if (states & ~0x07 || cmd > 2)
+ goto fail;
+ int ret = vgahw_save_restore(states | (cmd<<8), seg, data);
+ if (ret < 0)
+ goto fail;
+ if (cmd == 0)
+ regs->bx = ret / 64;
+ regs->al = 0x1c;
+fail:
+ return;
+}
+
+static void
+handle_10XX(struct bregs *regs)
+{
+ debug_stub(regs);
+}
+
+// INT 10h Video Support Service Entry Point
+void VISIBLE16
+handle_10(struct bregs *regs)
+{
+ debug_enter(regs, DEBUG_VGA_10);
+ switch (regs->ah) {
+ case 0x00: handle_1000(regs); break;
+ case 0x01: handle_1001(regs); break;
+ case 0x02: handle_1002(regs); break;
+ case 0x03: handle_1003(regs); break;
+ case 0x04: handle_1004(regs); break;
+ case 0x05: handle_1005(regs); break;
+ case 0x06: handle_1006(regs); break;
+ case 0x07: handle_1007(regs); break;
+ case 0x08: handle_1008(regs); break;
+ case 0x09: handle_1009(regs); break;
+ case 0x0a: handle_100a(regs); break;
+ case 0x0b: handle_100b(regs); break;
+ case 0x0c: handle_100c(regs); break;
+ case 0x0d: handle_100d(regs); break;
+ case 0x0e: handle_100e(regs); break;
+ case 0x0f: handle_100f(regs); break;
+ case 0x10: handle_1010(regs); break;
+ case 0x11: handle_1011(regs); break;
+ case 0x12: handle_1012(regs); break;
+ case 0x13: handle_1013(regs); break;
+ case 0x1a: handle_101a(regs); break;
+ case 0x1b: handle_101b(regs); break;
+ case 0x1c: handle_101c(regs); break;
+ case 0x4f: handle_104f(regs); break;
+ default: handle_10XX(regs); break;
+ }
+}
diff --git a/qemu/roms/seabios/vgasrc/vgabios.h b/qemu/roms/seabios/vgasrc/vgabios.h
new file mode 100644
index 000000000..fd796f2e6
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/vgabios.h
@@ -0,0 +1,149 @@
+#ifndef __VGABIOS_H
+#define __VGABIOS_H
+
+#include "config.h" // CONFIG_VGA_EMULATE_TEXT
+#include "types.h" // u8
+#include "farptr.h" // struct segoff_s
+#include "std/vga.h" // struct video_param_s
+
+// Save/Restore flags
+#define SR_HARDWARE 0x0001
+#define SR_BDA 0x0002
+#define SR_DAC 0x0004
+#define SR_REGISTERS 0x0008
+#define SR_SAVE 0x0100
+#define SR_RESTORE 0x0200
+
+// Mode flags
+#define MF_LEGACY 0x0001
+#define MF_GRAYSUM 0x0002
+#define MF_NOPALETTE 0x0008
+#define MF_CUSTOMCRTC 0x0800
+#define MF_LINEARFB 0x4000
+#define MF_NOCLEARMEM 0x8000
+#define MF_VBEFLAGS 0xfe00
+
+// Memory model types
+#define MM_TEXT 0x00
+#define MM_CGA 0x01
+#define MM_HERCULES 0x02
+#define MM_PLANAR 0x03
+#define MM_PACKED 0x04
+#define MM_NON_CHAIN_4_256 0x05
+#define MM_DIRECT 0x06
+#define MM_YUV 0x07
+
+struct vgamode_s {
+ u8 memmodel;
+ u16 width;
+ u16 height;
+ u8 depth;
+ u8 cwidth;
+ u8 cheight;
+ u16 sstart;
+};
+
+// Graphics pixel operations.
+struct gfx_op {
+ struct vgamode_s *vmode_g;
+ u32 linelength;
+ u32 displaystart;
+
+ u8 op;
+ u16 x, y;
+
+ u8 pixels[8];
+ u16 xlen, ylen;
+ u16 srcy;
+};
+
+#define GO_READ8 1
+#define GO_WRITE8 2
+#define GO_MEMSET 3
+#define GO_MEMMOVE 4
+
+// Custom internal storage in BDA
+#define VGA_CUSTOM_BDA 0xb9
+
+struct vga_bda_s {
+ u8 flags;
+ u16 vbe_mode;
+ u16 vgamode_offset;
+} PACKED;
+
+#define BF_PM_MASK 0x0f
+#define BF_EMULATE_TEXT 0x10
+#define BF_SWCURSOR 0x20
+
+#define GET_BDA_EXT(var) \
+ GET_FARVAR(SEG_BDA, ((struct vga_bda_s *)VGA_CUSTOM_BDA)->var)
+#define SET_BDA_EXT(var, val) \
+ SET_FARVAR(SEG_BDA, ((struct vga_bda_s *)VGA_CUSTOM_BDA)->var, (val))
+#define MASK_BDA_EXT(var, off, on) \
+ SET_BDA_EXT(var, (GET_BDA_EXT(var) & ~(off)) | (on))
+
+static inline int vga_emulate_text(void) {
+ return CONFIG_VGA_EMULATE_TEXT && GET_BDA_EXT(flags) & BF_EMULATE_TEXT;
+}
+
+// Debug settings
+#define DEBUG_VGA_POST 1
+#define DEBUG_VGA_10 3
+
+// vgafonts.c
+extern u8 vgafont8[];
+extern u8 vgafont14[];
+extern u8 vgafont16[];
+extern u8 vgafont14alt[];
+extern u8 vgafont16alt[];
+
+// vgainit.c
+extern struct video_save_pointer_s video_save_pointer_table;
+extern struct video_param_s video_param_table[29];
+
+// vgabios.c
+extern int VgaBDF;
+extern int HaveRunInit;
+#define SET_VGA(var, val) SET_FARVAR(get_global_seg(), (var), (val))
+struct carattr {
+ u8 car, attr, use_attr, pad;
+};
+struct cursorpos {
+ u8 x, y, page, pad;
+};
+int vga_bpp(struct vgamode_s *vmode_g);
+u16 calc_page_size(u8 memmodel, u16 width, u16 height);
+u16 get_cursor_shape(void);
+struct cursorpos get_cursor_pos(u8 page);
+int bda_save_restore(int cmd, u16 seg, void *data);
+struct vgamode_s *get_current_mode(void);
+int vga_set_mode(int mode, int flags);
+extern struct video_func_static static_functionality;
+
+// vgafb.c
+void init_gfx_op(struct gfx_op *op, struct vgamode_s *vmode_g);
+void handle_gfx_op(struct gfx_op *op);
+void *text_address(struct cursorpos cp);
+void vgafb_move_chars(struct cursorpos dest
+ , struct cursorpos src, struct cursorpos movesize);
+void vgafb_clear_chars(struct cursorpos dest
+ , struct carattr ca, struct cursorpos movesize);
+void vgafb_write_char(struct cursorpos cp, struct carattr ca);
+struct carattr vgafb_read_char(struct cursorpos cp);
+void vgafb_write_pixel(u8 color, u16 x, u16 y);
+u8 vgafb_read_pixel(u16 x, u16 y);
+void vgafb_set_swcursor(int enable);
+
+// vbe.c
+extern u32 VBE_total_memory;
+extern u32 VBE_capabilities;
+extern u32 VBE_framebuffer;
+extern u16 VBE_win_granularity;
+#define VBE_OEM_STRING "SeaBIOS VBE(C) 2011"
+#define VBE_VENDOR_STRING "SeaBIOS Developers"
+#define VBE_PRODUCT_STRING "SeaBIOS VBE Adapter"
+#define VBE_REVISION_STRING "Rev. 1"
+struct bregs;
+void handle_104f(struct bregs *regs);
+
+#endif // vgabios.h
diff --git a/qemu/roms/seabios/vgasrc/vgaentry.S b/qemu/roms/seabios/vgasrc/vgaentry.S
new file mode 100644
index 000000000..d9ebdb93c
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/vgaentry.S
@@ -0,0 +1,147 @@
+// Rom layout and bios assembler to C interface.
+//
+// Copyright (C) 2009-2013 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+
+#include "asm-offsets.h" // BREGS_*
+#include "config.h" // CONFIG_*
+#include "entryfuncs.S" // ENTRY_*
+
+
+/****************************************************************
+ * Rom Header
+ ****************************************************************/
+
+ .section .rom.header
+ .code16
+ .global _rom_header, _rom_header_size, _rom_header_checksum
+_rom_header:
+ .word 0xaa55
+_rom_header_size:
+ .byte 0
+_rom_header_entry:
+ jmp _optionrom_entry
+_rom_header_checksum:
+ .byte 0
+_rom_header_other:
+ .space 17
+_rom_header_pcidata:
+#if CONFIG_VGA_PCI == 1
+ .word rom_pci_data
+#else
+ .word 0
+#endif
+_rom_header_pnpdata:
+ .word 0
+_rom_header_other2:
+ .word 0
+_rom_header_signature:
+ .asciz "IBM"
+
+
+/****************************************************************
+ * Entry points
+ ****************************************************************/
+
+ // This macro implements a call while avoiding instructions
+ // that old versions of x86emu have problems with.
+ .macro VGA_CALLL cfunc
+#if CONFIG_VGA_FIXUP_ASM
+ pushw %ax
+ callw \cfunc
+#else
+ calll \cfunc
+#endif
+ .endm
+
+ // This macro is the same as ENTRY_ARG except VGA_CALLL is used.
+ .macro ENTRY_ARG_VGA cfunc
+ cli
+ cld
+ PUSHBREGS
+ movw %ss, %ax // Move %ss to %ds
+ movw %ax, %ds
+ movl %esp, %ebx // Backup %esp, then zero high bits
+ movzwl %sp, %esp
+ movl %esp, %eax // First arg is pointer to struct bregs
+ VGA_CALLL \cfunc
+ movl %ebx, %esp // Restore %esp (including high bits)
+ POPBREGS
+ .endm
+
+ DECLFUNC entry_104f05
+entry_104f05:
+ ENTRY_ARG_VGA vbe_104f05
+ lretw
+
+ DECLFUNC _optionrom_entry
+_optionrom_entry:
+ ENTRY_ARG_VGA vga_post
+ lretw
+
+ DECLFUNC entry_10
+entry_10:
+ ENTRY_ARG_VGA handle_10
+ iretw
+
+ // Entry point using extra stack
+ DECLFUNC entry_10_extrastack
+entry_10_extrastack:
+ cli
+ cld
+ pushw %ds // Set %ds:%eax to space on ExtraStack
+ pushl %eax
+ movw %cs:ExtraStackSeg, %ds
+ movl $(CONFIG_VGA_EXTRA_STACK_SIZE-PUSHBREGS_size-16), %eax
+ SAVEBREGS_POP_DSEAX // Save registers on extra stack
+ movl %esp, PUSHBREGS_size+8(%eax)
+ movw %ss, PUSHBREGS_size+12(%eax)
+ popl BREGS_code(%eax)
+ popw BREGS_flags(%eax)
+
+ movw %ds, %dx // Setup %ss/%esp and call function
+ movw %dx, %ss
+ movl %eax, %esp
+ VGA_CALLL handle_10
+
+ movl %esp, %eax // Restore registers and return
+ movw PUSHBREGS_size+12(%eax), %ss
+ movl PUSHBREGS_size+8(%eax), %esp
+ popl %edx
+ popw %dx
+ pushw BREGS_flags(%eax)
+ pushl BREGS_code(%eax)
+ RESTOREBREGS_DSEAX
+ iretw
+
+ // Timer irq handling
+ DECLFUNC entry_timer_hook
+entry_timer_hook:
+ ENTRY handle_timer_hook
+ ljmpw *%cs:Timer_Hook_Resume
+
+ // Timer irq handling on extra stack
+ DECLFUNC entry_timer_hook_extrastack
+entry_timer_hook_extrastack:
+ cli
+ cld
+ pushw %ds // Set %ds:%eax to space on ExtraStack
+ pushl %eax
+ movw %cs:ExtraStackSeg, %ds
+ movl $(CONFIG_VGA_EXTRA_STACK_SIZE-PUSHBREGS_size-8), %eax
+ SAVEBREGS_POP_DSEAX
+ movl %esp, PUSHBREGS_size(%eax)
+ movw %ss, PUSHBREGS_size+4(%eax)
+
+ movw %ds, %dx // Setup %ss/%esp and call function
+ movw %dx, %ss
+ movl %eax, %esp
+ calll handle_timer_hook
+
+ movl %esp, %eax // Restore registers and return
+ movw PUSHBREGS_size+4(%eax), %ss
+ movl PUSHBREGS_size(%eax), %esp
+ RESTOREBREGS_DSEAX
+ ljmpw *%cs:Timer_Hook_Resume
diff --git a/qemu/roms/seabios/vgasrc/vgafb.c b/qemu/roms/seabios/vgasrc/vgafb.c
new file mode 100644
index 000000000..1a94fcf70
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/vgafb.c
@@ -0,0 +1,702 @@
+// Code for manipulating VGA framebuffers.
+//
+// Copyright (C) 2009-2014 Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2001-2008 the LGPL VGABios developers Team
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "biosvar.h" // GET_BDA
+#include "byteorder.h" // cpu_to_be16
+#include "output.h" // dprintf
+#include "stdvga.h" // stdvga_planar4_plane
+#include "string.h" // memset_far
+#include "vgabios.h" // vgafb_scroll
+#include "vgahw.h" // vgahw_get_linelength
+
+static inline void
+memmove_stride(u16 seg, void *dst, void *src, int copylen, int stride, int lines)
+{
+ if (src < dst) {
+ dst += stride * (lines - 1);
+ src += stride * (lines - 1);
+ stride = -stride;
+ }
+ for (; lines; lines--, dst+=stride, src+=stride)
+ memcpy_far(seg, dst, seg, src, copylen);
+}
+
+static inline void
+memset_stride(u16 seg, void *dst, u8 val, int setlen, int stride, int lines)
+{
+ for (; lines; lines--, dst+=stride)
+ memset_far(seg, dst, val, setlen);
+}
+
+static inline void
+memset16_stride(u16 seg, void *dst, u16 val, int setlen, int stride, int lines)
+{
+ for (; lines; lines--, dst+=stride)
+ memset16_far(seg, dst, val, setlen);
+}
+
+
+/****************************************************************
+ * Basic stdvga graphic manipulation
+ ****************************************************************/
+
+static void
+gfx_planar(struct gfx_op *op)
+{
+ if (!CONFIG_VGA_STDVGA_PORTS)
+ return;
+ void *dest_far = (void*)(op->y * op->linelength + op->x / 8);
+ int plane;
+ switch (op->op) {
+ default:
+ case GO_READ8:
+ memset(op->pixels, 0, sizeof(op->pixels));
+ for (plane = 0; plane < 4; plane++) {
+ stdvga_planar4_plane(plane);
+ u8 data = GET_FARVAR(SEG_GRAPH, *(u8*)dest_far);
+ int pixel;
+ for (pixel=0; pixel<8; pixel++)
+ op->pixels[pixel] |= ((data>>(7-pixel)) & 1) << plane;
+ }
+ break;
+ case GO_WRITE8:
+ for (plane = 0; plane<4; plane++) {
+ stdvga_planar4_plane(plane);
+ u8 data = 0;
+ int pixel;
+ for (pixel=0; pixel<8; pixel++)
+ data |= ((op->pixels[pixel]>>plane) & 1) << (7-pixel);
+ SET_FARVAR(SEG_GRAPH, *(u8*)dest_far, data);
+ }
+ break;
+ case GO_MEMSET:
+ for (plane = 0; plane < 4; plane++) {
+ stdvga_planar4_plane(plane);
+ u8 data = (op->pixels[0] & (1<<plane)) ? 0xff : 0x00;
+ memset_stride(SEG_GRAPH, dest_far, data
+ , op->xlen / 8, op->linelength, op->ylen);
+ }
+ break;
+ case GO_MEMMOVE: ;
+ void *src_far = (void*)(op->srcy * op->linelength + op->x / 8);
+ for (plane = 0; plane < 4; plane++) {
+ stdvga_planar4_plane(plane);
+ memmove_stride(SEG_GRAPH, dest_far, src_far
+ , op->xlen / 8, op->linelength, op->ylen);
+ }
+ break;
+ }
+ stdvga_planar4_plane(-1);
+}
+
+static void
+gfx_cga(struct gfx_op *op)
+{
+ int bpp = GET_GLOBAL(op->vmode_g->depth);
+ void *dest_far = (void*)(op->y / 2 * op->linelength + op->x / 8 * bpp);
+ switch (op->op) {
+ default:
+ case GO_READ8:
+ if (op->y & 1)
+ dest_far += 0x2000;
+ if (bpp == 1) {
+ u8 data = GET_FARVAR(SEG_CTEXT, *(u8*)dest_far);
+ int pixel;
+ for (pixel=0; pixel<8; pixel++)
+ op->pixels[pixel] = (data >> (7-pixel)) & 1;
+ } else {
+ u16 data = GET_FARVAR(SEG_CTEXT, *(u16*)dest_far);
+ data = be16_to_cpu(data);
+ int pixel;
+ for (pixel=0; pixel<8; pixel++)
+ op->pixels[pixel] = (data >> ((7-pixel)*2)) & 3;
+ }
+ break;
+ case GO_WRITE8:
+ if (op->y & 1)
+ dest_far += 0x2000;
+ if (bpp == 1) {
+ u8 data = 0;
+ int pixel;
+ for (pixel=0; pixel<8; pixel++)
+ data |= (op->pixels[pixel] & 1) << (7-pixel);
+ SET_FARVAR(SEG_CTEXT, *(u8*)dest_far, data);
+ } else {
+ u16 data = 0;
+ int pixel;
+ for (pixel=0; pixel<8; pixel++)
+ data |= (op->pixels[pixel] & 3) << ((7-pixel) * 2);
+ data = cpu_to_be16(data);
+ SET_FARVAR(SEG_CTEXT, *(u16*)dest_far, data);
+ }
+ break;
+ case GO_MEMSET: ;
+ u8 data = op->pixels[0];
+ if (bpp == 1)
+ data = (data&1) | ((data&1)<<1);
+ data &= 3;
+ data |= (data<<2) | (data<<4) | (data<<6);
+ memset_stride(SEG_CTEXT, dest_far, data
+ , op->xlen / 8 * bpp, op->linelength, op->ylen / 2);
+ memset_stride(SEG_CTEXT, dest_far + 0x2000, data
+ , op->xlen / 8 * bpp, op->linelength, op->ylen / 2);
+ break;
+ case GO_MEMMOVE: ;
+ void *src_far = (void*)(op->srcy / 2 * op->linelength + op->x / 8 * bpp);
+ memmove_stride(SEG_CTEXT, dest_far, src_far
+ , op->xlen / 8 * bpp, op->linelength, op->ylen / 2);
+ memmove_stride(SEG_CTEXT, dest_far + 0x2000, src_far + 0x2000
+ , op->xlen / 8 * bpp, op->linelength, op->ylen / 2);
+ break;
+ }
+}
+
+static void
+gfx_packed(struct gfx_op *op)
+{
+ void *dest_far = (void*)(op->y * op->linelength + op->x);
+ switch (op->op) {
+ default:
+ case GO_READ8:
+ memcpy_far(GET_SEG(SS), op->pixels, SEG_GRAPH, dest_far, 8);
+ break;
+ case GO_WRITE8:
+ memcpy_far(SEG_GRAPH, dest_far, GET_SEG(SS), op->pixels, 8);
+ break;
+ case GO_MEMSET:
+ memset_stride(SEG_GRAPH, dest_far, op->pixels[0]
+ , op->xlen, op->linelength, op->ylen);
+ break;
+ case GO_MEMMOVE: ;
+ void *src_far = (void*)(op->srcy * op->linelength + op->x);
+ memmove_stride(SEG_GRAPH, dest_far, src_far
+ , op->xlen, op->linelength, op->ylen);
+ break;
+ }
+}
+
+
+/****************************************************************
+ * Direct framebuffers in high mem
+ ****************************************************************/
+
+// Use int 1587 call to copy memory to/from the framebuffer.
+static void
+memcpy_high(void *dest, void *src, u32 len)
+{
+ u64 gdt[6];
+ gdt[2] = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE((u32)src);
+ gdt[3] = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE((u32)dest);
+
+ // Call int 1587 to copy data.
+ len/=2;
+ u32 flags;
+ u32 eax = 0x8700;
+ u32 si = (u32)&gdt;
+ SET_SEG(ES, GET_SEG(SS));
+ asm volatile(
+ "stc\n"
+ "int $0x15\n"
+ "cli\n"
+ "cld\n"
+ "pushfl\n"
+ "popl %0\n"
+ : "=r" (flags), "+a" (eax), "+S" (si), "+c" (len)
+ : : "cc", "memory");
+}
+
+static void
+memmove_stride_high(void *dst, void *src, int copylen, int stride, int lines)
+{
+ if (src < dst) {
+ dst += stride * (lines - 1);
+ src += stride * (lines - 1);
+ stride = -stride;
+ }
+ for (; lines; lines--, dst+=stride, src+=stride)
+ memcpy_high(dst, src, copylen);
+}
+
+// Map a CGA color to a "direct" mode rgb value.
+static u32
+get_color(int depth, u8 attr)
+{
+ int rbits, gbits, bbits;
+ switch (depth) {
+ case 15: rbits=5; gbits=5; bbits=5; break;
+ case 16: rbits=5; gbits=6; bbits=5; break;
+ default:
+ case 24: rbits=8; gbits=8; bbits=8; break;
+ }
+ int h = (attr&8) ? 1 : 0;
+ int r = (attr&4) ? 2 : 0, g = (attr&2) ? 2 : 0, b = (attr&1) ? 2 : 0;
+ if ((attr & 0xf) == 6)
+ g = 1;
+ int rv = DIV_ROUND_CLOSEST(((1<<rbits) - 1) * (r + h), 3);
+ int gv = DIV_ROUND_CLOSEST(((1<<gbits) - 1) * (g + h), 3);
+ int bv = DIV_ROUND_CLOSEST(((1<<bbits) - 1) * (b + h), 3);
+ return (rv << (gbits+bbits)) + (gv << bbits) + bv;
+}
+
+// Find the closest attribute for a given framebuffer color
+static u8
+reverse_color(int depth, u32 color)
+{
+ int rbits, gbits, bbits;
+ switch (depth) {
+ case 15: rbits=5; gbits=5; bbits=5; break;
+ case 16: rbits=5; gbits=6; bbits=5; break;
+ default:
+ case 24: rbits=8; gbits=8; bbits=8; break;
+ }
+ int rv = (color >> (gbits+bbits)) & ((1<<rbits)-1);
+ int gv = (color >> bbits) & ((1<<gbits)-1);
+ int bv = color & ((1<<bbits)-1);
+ int r = DIV_ROUND_CLOSEST(rv * 3, (1<<rbits) - 1);
+ int g = DIV_ROUND_CLOSEST(gv * 3, (1<<gbits) - 1);
+ int b = DIV_ROUND_CLOSEST(bv * 3, (1<<bbits) - 1);
+ int h = r && g && b && (r != 2 || g != 2 || b != 2);
+ return (h ? 8 : 0) | ((r-h) ? 4 : 0) | ((g-h) ? 2 : 0) | ((b-h) ? 1 : 0);
+}
+
+static void
+gfx_direct(struct gfx_op *op)
+{
+ void *fb = (void*)GET_GLOBAL(VBE_framebuffer);
+ if (!fb)
+ return;
+ int depth = GET_GLOBAL(op->vmode_g->depth);
+ int bypp = DIV_ROUND_UP(depth, 8);
+ void *dest_far = (fb + op->displaystart + op->y * op->linelength
+ + op->x * bypp);
+ switch (op->op) {
+ default:
+ case GO_READ8: {
+ u8 data[64];
+ memcpy_high(MAKE_FLATPTR(GET_SEG(SS), data), dest_far, bypp * 8);
+ int i;
+ for (i=0; i<8; i++)
+ op->pixels[i] = reverse_color(depth, *(u32*)&data[i*bypp]);
+ break;
+ }
+ case GO_WRITE8: {
+ u8 data[64];
+ int i;
+ for (i=0; i<8; i++)
+ *(u32*)&data[i*bypp] = get_color(depth, op->pixels[i]);
+ memcpy_high(dest_far, MAKE_FLATPTR(GET_SEG(SS), data), bypp * 8);
+ break;
+ }
+ case GO_MEMSET: {
+ u32 color = get_color(depth, op->pixels[0]);
+ u8 data[64];
+ int i;
+ for (i=0; i<8; i++)
+ *(u32*)&data[i*bypp] = color;
+ memcpy_high(dest_far, MAKE_FLATPTR(GET_SEG(SS), data), bypp * 8);
+ memcpy_high(dest_far + bypp * 8, dest_far, op->xlen * bypp - bypp * 8);
+ for (i=1; i < op->ylen; i++)
+ memcpy_high(dest_far + op->linelength * i
+ , dest_far, op->xlen * bypp);
+ break;
+ }
+ case GO_MEMMOVE: ;
+ void *src_far = (fb + op->displaystart + op->srcy * op->linelength
+ + op->x * bypp);
+ memmove_stride_high(dest_far, src_far
+ , op->xlen * bypp, op->linelength, op->ylen);
+ break;
+ }
+}
+
+
+/****************************************************************
+ * Gfx interface
+ ****************************************************************/
+
+// Prepare a struct gfx_op for use.
+void
+init_gfx_op(struct gfx_op *op, struct vgamode_s *vmode_g)
+{
+ memset(op, 0, sizeof(*op));
+ op->vmode_g = vmode_g;
+ op->linelength = vgahw_get_linelength(vmode_g);
+ op->displaystart = vgahw_get_displaystart(vmode_g);
+}
+
+// Issue a graphics operation.
+void
+handle_gfx_op(struct gfx_op *op)
+{
+ switch (GET_GLOBAL(op->vmode_g->memmodel)) {
+ case MM_PLANAR:
+ gfx_planar(op);
+ break;
+ case MM_CGA:
+ gfx_cga(op);
+ break;
+ case MM_PACKED:
+ gfx_packed(op);
+ break;
+ case MM_DIRECT:
+ gfx_direct(op);
+ break;
+ default:
+ break;
+ }
+}
+
+// Move characters when in graphics mode.
+static void
+gfx_move_chars(struct vgamode_s *vmode_g, struct cursorpos dest
+ , struct cursorpos src, struct cursorpos movesize)
+{
+ struct gfx_op op;
+ init_gfx_op(&op, vmode_g);
+ op.x = dest.x * 8;
+ op.xlen = movesize.x * 8;
+ int cheight = GET_BDA(char_height);
+ op.y = dest.y * cheight;
+ op.ylen = movesize.y * cheight;
+ op.srcy = src.y * cheight;
+ op.op = GO_MEMMOVE;
+ handle_gfx_op(&op);
+}
+
+// Clear area of screen in graphics mode.
+static void
+gfx_clear_chars(struct vgamode_s *vmode_g, struct cursorpos dest
+ , struct carattr ca, struct cursorpos clearsize)
+{
+ struct gfx_op op;
+ init_gfx_op(&op, vmode_g);
+ op.x = dest.x * 8;
+ op.xlen = clearsize.x * 8;
+ int cheight = GET_BDA(char_height);
+ op.y = dest.y * cheight;
+ op.ylen = clearsize.y * cheight;
+ op.pixels[0] = ca.attr;
+ if (vga_emulate_text())
+ op.pixels[0] = ca.attr >> 4;
+ op.op = GO_MEMSET;
+ handle_gfx_op(&op);
+}
+
+// Return the font for a given character
+struct segoff_s
+get_font_data(u8 c)
+{
+ int char_height = GET_BDA(char_height);
+ struct segoff_s font;
+ if (char_height == 8 && c >= 128) {
+ font = GET_IVT(0x1f);
+ c -= 128;
+ } else {
+ font = GET_IVT(0x43);
+ }
+ font.offset += c * char_height;
+ return font;
+}
+
+// Write a character to the screen in graphics mode.
+static void
+gfx_write_char(struct vgamode_s *vmode_g
+ , struct cursorpos cp, struct carattr ca)
+{
+ if (cp.x >= GET_BDA(video_cols))
+ return;
+
+ struct segoff_s font = get_font_data(ca.car);
+ struct gfx_op op;
+ init_gfx_op(&op, vmode_g);
+ op.x = cp.x * 8;
+ int cheight = GET_BDA(char_height);
+ op.y = cp.y * cheight;
+ u8 fgattr = ca.attr, bgattr = 0x00;
+ int usexor = 0;
+ if (vga_emulate_text()) {
+ if (ca.use_attr) {
+ bgattr = fgattr >> 4;
+ fgattr = fgattr & 0x0f;
+ } else {
+ // Read bottom right pixel of the cell to guess bg color
+ op.op = GO_READ8;
+ op.y += cheight-1;
+ handle_gfx_op(&op);
+ op.y -= cheight-1;
+ bgattr = op.pixels[7];
+ fgattr = bgattr ^ 0x7;
+ }
+ } else if (fgattr & 0x80 && GET_GLOBAL(vmode_g->depth) < 8) {
+ usexor = 1;
+ fgattr &= 0x7f;
+ }
+ int i;
+ for (i = 0; i < cheight; i++, op.y++) {
+ u8 fontline = GET_FARVAR(font.seg, *(u8*)(font.offset+i));
+ if (usexor) {
+ op.op = GO_READ8;
+ handle_gfx_op(&op);
+ int j;
+ for (j = 0; j < 8; j++)
+ op.pixels[j] ^= (fontline & (0x80>>j)) ? fgattr : 0x00;
+ } else {
+ int j;
+ for (j = 0; j < 8; j++)
+ op.pixels[j] = (fontline & (0x80>>j)) ? fgattr : bgattr;
+ }
+ op.op = GO_WRITE8;
+ handle_gfx_op(&op);
+ }
+}
+
+// Read a character from the screen in graphics mode.
+static struct carattr
+gfx_read_char(struct vgamode_s *vmode_g, struct cursorpos cp)
+{
+ u8 lines[16];
+ int cheight = GET_BDA(char_height);
+ if (cp.x >= GET_BDA(video_cols) || cheight > ARRAY_SIZE(lines))
+ goto fail;
+
+ // Read cell from screen
+ struct gfx_op op;
+ init_gfx_op(&op, vmode_g);
+ op.op = GO_READ8;
+ op.x = cp.x * 8;
+ op.y = cp.y * cheight;
+ int car = 0;
+ u8 fgattr = 0x00, bgattr = 0x00;
+ if (vga_emulate_text()) {
+ // Read bottom right pixel of the cell to guess bg color
+ op.y += cheight-1;
+ handle_gfx_op(&op);
+ op.y -= cheight-1;
+ bgattr = op.pixels[7];
+ fgattr = bgattr ^ 0x7;
+ // Report space character for blank cells (skip null character check)
+ car = 1;
+ }
+ u8 i, j;
+ for (i=0; i<cheight; i++, op.y++) {
+ u8 line = 0;
+ handle_gfx_op(&op);
+ for (j=0; j<8; j++)
+ if (op.pixels[j] != bgattr) {
+ line |= 0x80 >> j;
+ fgattr = op.pixels[j];
+ }
+ lines[i] = line;
+ }
+
+ // Determine font
+ for (; car<256; car++) {
+ struct segoff_s font = get_font_data(car);
+ if (memcmp_far(GET_SEG(SS), lines
+ , font.seg, (void*)(font.offset+0), cheight) == 0)
+ return (struct carattr){car, fgattr | (bgattr << 4), 0};
+ }
+fail:
+ return (struct carattr){0, 0, 0};
+}
+
+// Draw/undraw a cursor on the framebuffer by xor'ing the cursor cell
+void
+gfx_set_swcursor(struct vgamode_s *vmode_g, int enable, struct cursorpos cp)
+{
+ u16 cursor_type = get_cursor_shape();
+ u8 start = cursor_type >> 8, end = cursor_type & 0xff;
+ struct gfx_op op;
+ init_gfx_op(&op, vmode_g);
+ op.x = cp.x * 8;
+ int cheight = GET_BDA(char_height);
+ op.y = cp.y * cheight + start;
+
+ int i;
+ for (i = start; i < cheight && i <= end; i++, op.y++) {
+ op.op = GO_READ8;
+ handle_gfx_op(&op);
+ int j;
+ for (j = 0; j < 8; j++)
+ op.pixels[j] ^= 0x07;
+ op.op = GO_WRITE8;
+ handle_gfx_op(&op);
+ }
+}
+
+// Set the pixel at the given position.
+void
+vgafb_write_pixel(u8 color, u16 x, u16 y)
+{
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (!vmode_g)
+ return;
+ vgafb_set_swcursor(0);
+
+ struct gfx_op op;
+ init_gfx_op(&op, vmode_g);
+ op.x = ALIGN_DOWN(x, 8);
+ op.y = y;
+ op.op = GO_READ8;
+ handle_gfx_op(&op);
+
+ int usexor = color & 0x80 && GET_GLOBAL(vmode_g->depth) < 8;
+ if (usexor)
+ op.pixels[x & 0x07] ^= color & 0x7f;
+ else
+ op.pixels[x & 0x07] = color;
+ op.op = GO_WRITE8;
+ handle_gfx_op(&op);
+}
+
+// Return the pixel at the given position.
+u8
+vgafb_read_pixel(u16 x, u16 y)
+{
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (!vmode_g)
+ return 0;
+ vgafb_set_swcursor(0);
+
+ struct gfx_op op;
+ init_gfx_op(&op, vmode_g);
+ op.x = ALIGN_DOWN(x, 8);
+ op.y = y;
+ op.op = GO_READ8;
+ handle_gfx_op(&op);
+
+ return op.pixels[x & 0x07];
+}
+
+
+/****************************************************************
+ * Text ops
+ ****************************************************************/
+
+// Return the fb offset for the given character address when in text mode.
+void *
+text_address(struct cursorpos cp)
+{
+ int stride = GET_BDA(video_cols) * 2;
+ u32 pageoffset = GET_BDA(video_pagesize) * cp.page;
+ return (void*)pageoffset + cp.y * stride + cp.x * 2;
+}
+
+// Move characters on screen.
+void
+vgafb_move_chars(struct cursorpos dest
+ , struct cursorpos src, struct cursorpos movesize)
+{
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (!vmode_g)
+ return;
+ vgafb_set_swcursor(0);
+
+ if (GET_GLOBAL(vmode_g->memmodel) != MM_TEXT) {
+ gfx_move_chars(vmode_g, dest, src, movesize);
+ return;
+ }
+
+ int stride = GET_BDA(video_cols) * 2;
+ memmove_stride(GET_GLOBAL(vmode_g->sstart)
+ , text_address(dest), text_address(src)
+ , movesize.x * 2, stride, movesize.y);
+}
+
+// Clear area of screen.
+void
+vgafb_clear_chars(struct cursorpos dest
+ , struct carattr ca, struct cursorpos clearsize)
+{
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (!vmode_g)
+ return;
+ vgafb_set_swcursor(0);
+
+ if (GET_GLOBAL(vmode_g->memmodel) != MM_TEXT) {
+ gfx_clear_chars(vmode_g, dest, ca, clearsize);
+ return;
+ }
+
+ int stride = GET_BDA(video_cols) * 2;
+ u16 attr = ((ca.use_attr ? ca.attr : 0x07) << 8) | ca.car;
+ memset16_stride(GET_GLOBAL(vmode_g->sstart), text_address(dest), attr
+ , clearsize.x * 2, stride, clearsize.y);
+}
+
+// Write a character to the screen.
+void
+vgafb_write_char(struct cursorpos cp, struct carattr ca)
+{
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (!vmode_g)
+ return;
+ vgafb_set_swcursor(0);
+
+ if (GET_GLOBAL(vmode_g->memmodel) != MM_TEXT) {
+ gfx_write_char(vmode_g, cp, ca);
+ return;
+ }
+
+ void *dest_far = text_address(cp);
+ if (ca.use_attr) {
+ u16 dummy = (ca.attr << 8) | ca.car;
+ SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *(u16*)dest_far, dummy);
+ } else {
+ SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *(u8*)dest_far, ca.car);
+ }
+}
+
+// Return the character at the given position on the screen.
+struct carattr
+vgafb_read_char(struct cursorpos cp)
+{
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (!vmode_g)
+ return (struct carattr){0, 0, 0};
+ vgafb_set_swcursor(0);
+
+ if (GET_GLOBAL(vmode_g->memmodel) != MM_TEXT)
+ return gfx_read_char(vmode_g, cp);
+
+ u16 *dest_far = text_address(cp);
+ u16 v = GET_FARVAR(GET_GLOBAL(vmode_g->sstart), *dest_far);
+ return (struct carattr){v, v>>8, 0};
+}
+
+// Draw/undraw a cursor on the screen
+void
+vgafb_set_swcursor(int enable)
+{
+ if (!vga_emulate_text())
+ return;
+ u8 flags = GET_BDA_EXT(flags);
+ if (!!(flags & BF_SWCURSOR) == enable)
+ // Already in requested mode.
+ return;
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (!vmode_g)
+ return;
+ struct cursorpos cp = get_cursor_pos(0xff);
+ if (cp.x >= GET_BDA(video_cols) || cp.y > GET_BDA(video_rows)
+ || GET_BDA(cursor_type) >= 0x2000)
+ // Cursor not visible
+ return;
+
+ SET_BDA_EXT(flags, (flags & ~BF_SWCURSOR) | (enable ? BF_SWCURSOR : 0));
+
+ if (GET_GLOBAL(vmode_g->memmodel) != MM_TEXT) {
+ gfx_set_swcursor(vmode_g, enable, cp);
+ return;
+ }
+
+ // In text mode, swap foreground and background attributes for cursor
+ void *dest_far = text_address(cp) + 1;
+ u8 attr = GET_FARVAR(GET_GLOBAL(vmode_g->sstart), *(u8*)dest_far);
+ attr = (attr >> 4) | (attr << 4);
+ SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *(u8*)dest_far, attr);
+}
diff --git a/qemu/roms/seabios/vgasrc/vgafonts.c b/qemu/roms/seabios/vgasrc/vgafonts.c
new file mode 100644
index 000000000..47a6437f2
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/vgafonts.c
@@ -0,0 +1,785 @@
+#include "vgabios.h" // vgafont8
+
+/*
+ * These fonts come from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip
+ * The package is (c) by Joseph Gil
+ * The individual fonts are public domain
+ */
+u8 vgafont8[256 * 8] VAR16 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e,
+ 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e,
+ 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00,
+ 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00,
+ 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c,
+ 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c,
+ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00,
+ 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff,
+ 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
+ 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff,
+ 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78,
+ 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18,
+ 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0,
+ 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0,
+ 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99,
+ 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00,
+ 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00,
+ 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
+ 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00,
+ 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78,
+ 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00,
+ 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff,
+ 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
+ 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00,
+ 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00,
+ 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00,
+ 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00,
+ 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00,
+ 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,
+ 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00,
+ 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00,
+ 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00,
+ 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00,
+ 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
+ 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
+ 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60,
+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00,
+ 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00,
+ 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00,
+ 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00,
+ 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00,
+ 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00,
+ 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00,
+ 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00,
+ 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00,
+ 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00,
+ 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00,
+ 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00,
+ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00,
+ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60,
+ 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00,
+ 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
+ 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00,
+ 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00,
+ 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00,
+ 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00,
+ 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00,
+ 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00,
+ 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00,
+ 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00,
+ 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00,
+ 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00,
+ 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00,
+ 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00,
+ 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00,
+ 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00,
+ 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00,
+ 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00,
+ 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00,
+ 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
+ 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00,
+ 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00,
+ 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00,
+ 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00,
+ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00,
+ 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00,
+ 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00,
+ 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00,
+ 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00,
+ 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
+ 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00,
+ 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
+ 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
+ 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00,
+ 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00,
+ 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00,
+ 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
+ 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00,
+ 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
+ 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00,
+ 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78,
+ 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00,
+ 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00,
+ 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00,
+ 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00,
+ 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0,
+ 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e,
+ 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00,
+ 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00,
+ 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00,
+ 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
+ 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00,
+ 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00,
+ 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00,
+ 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
+ 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00,
+ 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00,
+ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
+ 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00,
+ 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
+ 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78,
+ 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
+ 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
+ 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00,
+ 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
+ 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
+ 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
+ 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38,
+ 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
+ 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
+ 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
+ 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
+ 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00,
+ 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00,
+ 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00,
+ 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00,
+ 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00,
+ 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
+ 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
+ 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
+ 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
+ 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
+ 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
+ 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00,
+ 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00,
+ 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18,
+ 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00,
+ 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30,
+ 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7,
+ 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70,
+ 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
+ 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
+ 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
+ 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00,
+ 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00,
+ 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00,
+ 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00,
+ 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00,
+ 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00,
+ 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f,
+ 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03,
+ 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00,
+ 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00,
+ 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00,
+ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
+ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+ 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00,
+ 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0,
+ 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00,
+ 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00,
+ 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00,
+ 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00,
+ 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0,
+ 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00,
+ 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc,
+ 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00,
+ 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00,
+ 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00,
+ 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00,
+ 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0,
+ 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00,
+ 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00,
+ 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00,
+ 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00,
+ 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00,
+ 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00,
+ 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70,
+ 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00,
+ 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00,
+ 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+ 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c,
+ 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00,
+ 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+u8 vgafont14[256 * 14] VAR16 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x7e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00,
+ 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x66, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x6c, 0x78, 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00,
+ 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00,
+ 0x00, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
+ 0x00, 0xc6, 0xc6, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00,
+ 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
+ 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00,
+ 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+ 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0x40, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00,
+ 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+u8 vgafont16[256 * 16] VAR16 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
+ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
+ 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00,
+ 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+ 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+u8 vgafont14alt[1] VAR16;
+u8 vgafont16alt[1] VAR16;
diff --git a/qemu/roms/seabios/vgasrc/vgahw.h b/qemu/roms/seabios/vgasrc/vgahw.h
new file mode 100644
index 000000000..39f818ab5
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/vgahw.h
@@ -0,0 +1,143 @@
+#ifndef __VGAHW_H
+#define __VGAHW_H
+
+#include "types.h" // u8
+#include "config.h" // CONFIG_*
+
+#include "cbvga.h" // cbvga_setup
+#include "clext.h" // clext_set_mode
+#include "bochsvga.h" // bochsvga_set_mode
+#include "stdvga.h" // stdvga_set_mode
+#include "geodevga.h" // geodevga_setup
+
+static inline struct vgamode_s *vgahw_find_mode(int mode) {
+ if (CONFIG_VGA_CIRRUS)
+ return clext_find_mode(mode);
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_find_mode(mode);
+ if (CONFIG_VGA_COREBOOT)
+ return cbvga_find_mode(mode);
+ return stdvga_find_mode(mode);
+}
+
+static inline int vgahw_set_mode(struct vgamode_s *vmode_g, int flags) {
+ if (CONFIG_VGA_CIRRUS)
+ return clext_set_mode(vmode_g, flags);
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_set_mode(vmode_g, flags);
+ if (CONFIG_VGA_COREBOOT)
+ return cbvga_set_mode(vmode_g, flags);
+ return stdvga_set_mode(vmode_g, flags);
+}
+
+static inline void vgahw_list_modes(u16 seg, u16 *dest, u16 *last) {
+ if (CONFIG_VGA_CIRRUS)
+ clext_list_modes(seg, dest, last);
+ else if (CONFIG_VGA_BOCHS)
+ bochsvga_list_modes(seg, dest, last);
+ else if (CONFIG_VGA_COREBOOT)
+ cbvga_list_modes(seg, dest, last);
+ else
+ stdvga_list_modes(seg, dest, last);
+}
+
+static inline int vgahw_setup(void) {
+ if (CONFIG_VGA_CIRRUS)
+ return clext_setup();
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_setup();
+ if (CONFIG_VGA_GEODEGX2 || CONFIG_VGA_GEODELX)
+ return geodevga_setup();
+ if (CONFIG_VGA_COREBOOT)
+ return cbvga_setup();
+ return stdvga_setup();
+}
+
+static inline int vgahw_get_window(struct vgamode_s *vmode_g, int window) {
+ if (CONFIG_VGA_CIRRUS)
+ return clext_get_window(vmode_g, window);
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_get_window(vmode_g, window);
+ if (CONFIG_VGA_COREBOOT)
+ return cbvga_get_window(vmode_g, window);
+ return stdvga_get_window(vmode_g, window);
+}
+
+static inline int vgahw_set_window(struct vgamode_s *vmode_g, int window
+ , int val) {
+ if (CONFIG_VGA_CIRRUS)
+ return clext_set_window(vmode_g, window, val);
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_set_window(vmode_g, window, val);
+ if (CONFIG_VGA_COREBOOT)
+ return cbvga_set_window(vmode_g, window, val);
+ return stdvga_set_window(vmode_g, window, val);
+}
+
+static inline int vgahw_get_linelength(struct vgamode_s *vmode_g) {
+ if (CONFIG_VGA_CIRRUS)
+ return clext_get_linelength(vmode_g);
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_get_linelength(vmode_g);
+ if (CONFIG_VGA_COREBOOT)
+ return cbvga_get_linelength(vmode_g);
+ return stdvga_get_linelength(vmode_g);
+}
+
+static inline int vgahw_set_linelength(struct vgamode_s *vmode_g, int val) {
+ if (CONFIG_VGA_CIRRUS)
+ return clext_set_linelength(vmode_g, val);
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_set_linelength(vmode_g, val);
+ if (CONFIG_VGA_COREBOOT)
+ return cbvga_set_linelength(vmode_g, val);
+ return stdvga_set_linelength(vmode_g, val);
+}
+
+static inline int vgahw_get_displaystart(struct vgamode_s *vmode_g) {
+ if (CONFIG_VGA_CIRRUS)
+ return clext_get_displaystart(vmode_g);
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_get_displaystart(vmode_g);
+ if (CONFIG_VGA_COREBOOT)
+ return cbvga_get_displaystart(vmode_g);
+ return stdvga_get_displaystart(vmode_g);
+}
+
+static inline int vgahw_set_displaystart(struct vgamode_s *vmode_g, int val) {
+ if (CONFIG_VGA_CIRRUS)
+ return clext_set_displaystart(vmode_g, val);
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_set_displaystart(vmode_g, val);
+ if (CONFIG_VGA_COREBOOT)
+ return cbvga_set_displaystart(vmode_g, val);
+ return stdvga_set_displaystart(vmode_g, val);
+}
+
+static inline int vgahw_get_dacformat(struct vgamode_s *vmode_g) {
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_get_dacformat(vmode_g);
+ if (CONFIG_VGA_COREBOOT)
+ return cbvga_get_dacformat(vmode_g);
+ return stdvga_get_dacformat(vmode_g);
+}
+
+static inline int vgahw_set_dacformat(struct vgamode_s *vmode_g, int val) {
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_set_dacformat(vmode_g, val);
+ if (CONFIG_VGA_COREBOOT)
+ return cbvga_set_dacformat(vmode_g, val);
+ return stdvga_set_dacformat(vmode_g, val);
+}
+
+static inline int vgahw_save_restore(int cmd, u16 seg, void *data) {
+ if (CONFIG_VGA_CIRRUS)
+ return clext_save_restore(cmd, seg, data);
+ if (CONFIG_VGA_BOCHS)
+ return bochsvga_save_restore(cmd, seg, data);
+ if (CONFIG_VGA_COREBOOT)
+ return cbvga_save_restore(cmd, seg, data);
+ return stdvga_save_restore(cmd, seg, data);
+}
+
+#endif // vgahw.h
diff --git a/qemu/roms/seabios/vgasrc/vgainit.c b/qemu/roms/seabios/vgasrc/vgainit.c
new file mode 100644
index 000000000..8d1226182
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/vgainit.c
@@ -0,0 +1,195 @@
+// Main VGA bios initialization
+//
+// Copyright (C) 2009-2013 Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2001-2008 the LGPL VGABios developers Team
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "biosvar.h" // SET_BDA
+#include "bregs.h" // struct bregs
+#include "hw/pci.h" // pci_config_readw
+#include "hw/pci_regs.h" // PCI_VENDOR_ID
+#include "hw/serialio.h" // serial_debug_preinit
+#include "output.h" // dprintf
+#include "std/optionrom.h" // struct pci_data
+#include "std/pmm.h" // struct pmmheader
+#include "string.h" // checksum_far
+#include "util.h" // VERSION
+#include "vgabios.h" // video_save_pointer_table
+#include "vgahw.h" // vgahw_setup
+
+struct video_save_pointer_s video_save_pointer_table VAR16;
+
+struct video_param_s video_param_table[29] VAR16;
+
+// Type of emulator platform - for dprintf with certain compile options.
+int PlatformRunningOn VAR16;
+
+
+/****************************************************************
+ * PCI Data
+ ****************************************************************/
+
+struct pci_data rom_pci_data VAR16 VISIBLE16 = {
+ .signature = PCI_ROM_SIGNATURE,
+ .vendor = CONFIG_VGA_VID,
+ .device = CONFIG_VGA_DID,
+ .dlen = 0x18,
+ .class_hi = 0x300,
+ .irevision = 1,
+ .type = PCIROM_CODETYPE_X86,
+ .indicator = 0x80,
+};
+
+
+/****************************************************************
+ * PMM call and extra stack setup
+ ****************************************************************/
+
+u16 ExtraStackSeg VAR16 VISIBLE16;
+
+static void
+allocate_extra_stack(void)
+{
+ if (!CONFIG_VGA_ALLOCATE_EXTRA_STACK)
+ return;
+ u32 pmmscan;
+ for (pmmscan=0; pmmscan < BUILD_BIOS_SIZE; pmmscan+=16) {
+ struct pmmheader *pmm = (void*)pmmscan;
+ if (GET_FARVAR(SEG_BIOS, pmm->signature) != PMM_SIGNATURE)
+ continue;
+ if (checksum_far(SEG_BIOS, pmm, GET_FARVAR(SEG_BIOS, pmm->length)))
+ continue;
+ struct segoff_s entry = GET_FARVAR(SEG_BIOS, pmm->entry);
+ dprintf(1, "Attempting to allocate VGA stack via pmm call to %04x:%04x\n"
+ , entry.seg, entry.offset);
+ u16 res1, res2;
+ asm volatile(
+ "pushl %0\n"
+ "pushw $(8|1)\n" // Permanent low memory request
+ "pushl $0xffffffff\n" // Anonymous handle
+ "pushl $" __stringify(CONFIG_VGA_EXTRA_STACK_SIZE/16) "\n"
+ "pushw $0x00\n" // PMM allocation request
+ "lcallw *12(%%esp)\n"
+ "addl $16, %%esp\n"
+ "cli\n"
+ "cld\n"
+ : "+r" (entry.segoff), "=a" (res1), "=d" (res2) : : "cc", "memory");
+ u32 res = res1 | (res2 << 16);
+ if (!res || res == PMM_FUNCTION_NOT_SUPPORTED)
+ return;
+ dprintf(1, "VGA stack allocated at %x\n", res);
+ SET_VGA(ExtraStackSeg, res >> 4);
+ extern void entry_10_extrastack(void);
+ SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10_extrastack));
+ return;
+ }
+}
+
+
+/****************************************************************
+ * Timer hook
+ ****************************************************************/
+
+struct segoff_s Timer_Hook_Resume VAR16 VISIBLE16;
+
+void VISIBLE16
+handle_timer_hook(void)
+{
+ if (!vga_emulate_text())
+ return;
+ vgafb_set_swcursor(GET_BDA(timer_counter) % 18 < 9);
+}
+
+static void
+hook_timer_irq(void)
+{
+ if (!CONFIG_VGA_EMULATE_TEXT)
+ return;
+ extern void entry_timer_hook(void);
+ extern void entry_timer_hook_extrastack(void);
+ struct segoff_s oldirq = GET_IVT(0x08);
+ struct segoff_s newirq = SEGOFF(get_global_seg(), (u32)entry_timer_hook);
+ if (CONFIG_VGA_ALLOCATE_EXTRA_STACK && GET_GLOBAL(ExtraStackSeg))
+ newirq = SEGOFF(get_global_seg(), (u32)entry_timer_hook_extrastack);
+ dprintf(1, "Hooking hardware timer irq (old=%x new=%x)\n"
+ , oldirq.segoff, newirq.segoff);
+ SET_VGA(Timer_Hook_Resume, oldirq);
+ SET_IVT(0x08, newirq);
+}
+
+
+/****************************************************************
+ * VGA post
+ ****************************************************************/
+
+static void
+init_bios_area(void)
+{
+ // init detected hardware BIOS Area
+ // set 80x25 color (not clear from RBIL but usual)
+ set_equipment_flags(0x30, 0x20);
+
+ // Set the basic modeset options
+ SET_BDA(modeset_ctl, 0x51);
+
+ SET_BDA(dcc_index, CONFIG_VGA_STDVGA_PORTS ? 0x08 : 0xff);
+ SET_BDA(video_savetable
+ , SEGOFF(get_global_seg(), (u32)&video_save_pointer_table));
+
+ // FIXME
+ SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but...
+ SET_BDA(video_pal, 0x00); // Unavailable on vanilla vga, but...
+}
+
+int VgaBDF VAR16 = -1;
+int HaveRunInit VAR16;
+
+void VISIBLE16
+vga_post(struct bregs *regs)
+{
+ serial_debug_preinit();
+ dprintf(1, "Start SeaVGABIOS (version %s)\n", VERSION);
+ debug_enter(regs, DEBUG_VGA_POST);
+
+ if (CONFIG_VGA_PCI && !GET_GLOBAL(HaveRunInit)) {
+ u16 bdf = regs->ax;
+ if ((pci_config_readw(bdf, PCI_VENDOR_ID)
+ == GET_GLOBAL(rom_pci_data.vendor))
+ && (pci_config_readw(bdf, PCI_DEVICE_ID)
+ == GET_GLOBAL(rom_pci_data.device)))
+ SET_VGA(VgaBDF, bdf);
+ }
+
+ int ret = vgahw_setup();
+ if (ret) {
+ dprintf(1, "Failed to initialize VGA hardware. Exiting.\n");
+ return;
+ }
+
+ if (GET_GLOBAL(HaveRunInit))
+ return;
+
+ init_bios_area();
+
+ SET_VGA(video_save_pointer_table.videoparam
+ , SEGOFF(get_global_seg(), (u32)video_param_table));
+ if (CONFIG_VGA_STDVGA_PORTS)
+ stdvga_build_video_param();
+
+ extern void entry_10(void);
+ SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10));
+
+ allocate_extra_stack();
+
+ hook_timer_irq();
+
+ SET_VGA(HaveRunInit, 1);
+
+ // Fixup checksum
+ extern u8 _rom_header_size, _rom_header_checksum;
+ SET_VGA(_rom_header_checksum, 0);
+ u8 sum = -checksum_far(get_global_seg(), 0,
+ GET_GLOBAL(_rom_header_size) * 512);
+ SET_VGA(_rom_header_checksum, sum);
+}
diff --git a/qemu/roms/seabios/vgasrc/vgalayout.lds.S b/qemu/roms/seabios/vgasrc/vgalayout.lds.S
new file mode 100644
index 000000000..533734d85
--- /dev/null
+++ b/qemu/roms/seabios/vgasrc/vgalayout.lds.S
@@ -0,0 +1,23 @@
+// Linker definitions for an option rom
+//
+// Copyright (C) 2009 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH("i386")
+ENTRY(_optionrom_entry)
+SECTIONS
+{
+ .text 0 : {
+ KEEP(*(.rom.header))
+ *(.text.*)
+ _rodata = . ;
+ *(.rodata*)
+ *(.data16.*)
+ }
+
+ // Discard regular data sections to force a link error if
+ // 16bit code attempts to access data not marked with VAR16.
+ /DISCARD/ : { *(.text*) *(.rodata*) *(.data*) *(.bss*) *(COMMON) }
+}